Как создать окно QtQuick вне основного потока

Я хотел бы иметь основной поток, который создает экземпляр класса, который расширяет QQuickView и перемещает его во второй поток.

В идеале я хотел бы сделать что-то вроде этого:

main.cpp

int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);
    MyClass myClassObj;

    myClassObj.init();

    return 0;
}

MyClass.cpp

void init()
{
    MyQtQuickClass view;

    QThread* GUIthread = new QThread(this);

    view.moveToThread(GUIthread);
    QObject::connect(GUIthread, SIGNAL(started()), &view, SLOT(init()));

    GUIthread.start();
}

MyQtQuickCLass.cpp

void init()
{
    QQmlContext* rootContext = this->rootContext();

    // Setup view code here

    this->show();

    QGuiApplication::instance()->exec();
}

Что-то вроде этого я получаю эту ошибку: QQmlEngine: недопустимая попытка подключения к QQmlContext(0x120fc60), который находится в потоке, отличном от механизма QML QQmlEngine(0xdf6e70).

Есть ли обходной путь? Или способ создать движок QML прямо во втором потоке?

2 ответа

Решение

Если вы хотите, чтобы QQuickView жил за пределами main() нить, то вы должны:

  1. Создать новый std::thread (НЕ QThreadпотому что это QObject так что это не должно быть создано до вашего QGuiApplication)
  2. Запустить init() функция в этой теме. Пусть это создаст QGuiApplication и запустить цикл событий.
  3. Создайте свой QQuickView в этой теме тоже.
  4. Убедитесь, что все ваши объекты GUI доступны только из этого потока.
  5. Убедитесь, что ваш main() поток не создает QObjectдо тех пор, пока после QGuiApplication был создан в другой вашей теме.

См. Как избежать Qt app.exec(), блокирующего основной поток, для получения более подробной информации.

QObjects имеют сродство потока с родителем QObjectили текущий поток, если у них нет родителя. Скорее всего - в вашем примере - некоторые QObjectсозданные во время создания MyQtQuickClass иметь сходство с тем, в котором они были созданы. Создание MyQtQuickClass в GUIthread бы решить это.

Однако все окна Qt должны работать в том же потоке, что и QGuiApplicationи ваше приложение, скорее всего, зависнет, если вы попытаетесь.

Другие вопросы по тегам