如何在主线程外创建QtQuick窗口

时间:2016-06-04 18:34:17

标签: c++ multithreading qt qtquick2 qt-quick

我想要的是一个主线程,它实例化一个扩展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:非法尝试连接到与QML引擎QQmlEngine(0xdf6e70)不同的线程中的QQmlContext(0x120fc60)。

有解决方法吗?还是直接在第二个线程中创建QML引擎的方法?

2 个答案:

答案 0 :(得分:2)

QObject与父QObject的主题具有线程关联,如果他们没有父主,则为当前主题。最有可能的是 - 在您的示例中 - 在QObject实例化期间创建的某些MyQtQuickClass与创建它们的线程具有亲缘关系。在MyQtQuickClass中创建GUIthread可以解决此问题。

但是,所有Qt窗口必须在与QGuiApplication相同的线程中运行,如果您尝试过,您的应用程序很可能会崩溃。

答案 1 :(得分:2)

如果您希望QQuickView位于main()主题之外,那么您必须:

  1. 创建一个新的std::thread(不是QThread,因为它是QObject所以不能在QGuiApplication之前创建
  2. 在该线程中运行init()函数。让它实例化您的QGuiApplication并启动事件循环。
  3. 也在该帖子中创建QQuickView
  4. 确保仅从该线程访问所有 GUI对象。
  5. 确保您的main()主题在您的其他主题中创建QObject之后才创建任何QGuiApplication
  6. 有关详细信息,请参阅How to avoid Qt app.exec() blocking main thread