W
W
WTFAYD2018-03-27 18:43:48
User interface
WTFAYD, 2018-03-27 18:43:48

What is the correct way to use QWidget in QML?

Hello!
There is such problem - it is necessary to present QWidget as QML Item. Ran the following code:

/* qmlwidget.h */

#include <QQuickPaintedItem>
#include <QPushButton>

class QmlWidget : public QQuickPaintedItem
{
    Q_OBJECT

public:
    explicit QmlWidget(QQuickItem* parent = 0);
    void paint(QPainter* painter);

private:
    QPushButton* w;
};

/* qmlwidget.cpp */

#include "qmlwidget.h"

QmlWidget::QmlWidget(QQuickItem* parent) :
    QQuickPaintedItem(parent)
{
    w = new QPushButton;
}

void QmlWidget::paint(QPainter *painter) {
    w->render(painter);
}

/* main.cpp */

#include <QQmlApplicationEngine>
#include <QApplication>
#include "qmlwidget.h"

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    qmlRegisterType<QmlWidget>("QmlWidget",1,0,"QmlWidget");
    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    return app.exec();
}

/* main.qml */

import QtQuick 2.6
import QtQuick.Window 2.2
import QmlWidget 1.0

Window {
    visible: true
    width: 640
    height: 320

    QmlWidget {
        anchors.fill: parent
    }
}

And the weirdest thing is that it works on Linux (but throws warnings) and doesn't work on Windows.
Linux warnings:
QApplication: invalid style override passed, ignoring it.
Xlib: extension "NV-GLX" missing on display ":0".
QObject::~QObject: Timers cannot be stopped from another thread

Runtime error on Windows:
ASSERT failure in QCoreApplication::sendEvent: "Cannot send events to objects owned by a different thread. Current thread 0x0x34685758. Receiver '' (of type 'QPushButton ') was created in thread 0x0x326cc710", file kernel\qcoreapplication.cpp, line 589
An error occurs when rendering a widget in paint().
Please tell me what is the problem?

Answer the question

In order to leave comments, you need to log in

1 answer(s)
A
Ariox41, 2018-03-28
@Ariox41

The line w = new QPushButton;does not specify a parent, which means the button is created for the main thread's event loop. However, QML can run on its own thread (which has its own event loop), which causes the button to be created on the QML thread, but for the main thread's event loop. This is what is written in the error message. Passing a parent running on a QML thread should help: w = new QPushButton(this);. In this case, the button will use the parent's event loop (this already knows from its parent which thread it is in).

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question