Как правильно использовать QWidget в QML?

Здравствуйте!

Есть такая проблема - нужно QWidget представить как QML Item. Набросал такой код:

/* 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
    }
}


И, что самое странное, он работает на Linux (но выдает предупреждения) и не работает в Windows.

Предупреждения в Linux:

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 ошибка в 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

Ошибка возникает при рендере виджета в paint().

Подскажите пожалуйста, в чем проблема?
  • Вопрос задан
  • 1070 просмотров
Пригласить эксперта
Ответы на вопрос 1
@Ariox41
В строке w = new QPushButton; не указан родитель, а значит кнопка создаётся для цикла событий основного потока. Однако QML может работать в своём собственном потоке (с которым связан свой цикл событий), из-за чего кнопка создаётся в потоке QML, но для цикла событий основного потока. Об этом и написано в сообщении об ошибке. Должна помочь передача родителя, работающего в потоке QML: w = new QPushButton(this);. При этом кнопка будет использовать цикл событий родителя (this уже от своего родителя знает, в каком он потоке).
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы