如何在主线程外创建 QtQuick window
How to create QtQuick window outside the main thread
我想要的是一个主线程,它实例化一个扩展 QQuickView 并将其移动到第二个线程的 class。
理想情况下,我想做这样的事情:
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引擎的方法?
QObject
与父 QObject
的线程或当前线程(如果它们没有父线程)具有线程关联。在您的示例中,很可能在 MyQtQuickClass
的实例化期间创建的一些 QObject
与创建它们的线程具有亲和力。在 GUIthread
中创建 MyQtQuickClass
可以解决这个问题。
但是,所有Qt windows 必须 运行与QGuiApplication
在同一个线程中,如果您尝试,您的应用程序很可能会崩溃。
如果您希望 QQuickView 位于 main()
线程之外,那么您必须:
- 创建一个新的
std::thread
(不是 QThread
,因为它是 QObject
,所以不能在您的 QGuiApplication
之前创建)
- 运行 该线程中的一个
init()
函数。让它实例化您的 QGuiApplication
并启动事件循环。
- 也在该线程中创建您的
QQuickView
。
- 确保仅从该线程访问所有 GUI 对象。
- 确保您的
main()
线程在您的 QGuiApplication
在您的其他线程中创建之前不会创建任何 QObject
。
有关详细信息,请参阅 How to avoid Qt app.exec() blocking main thread。
我想要的是一个主线程,它实例化一个扩展 QQuickView 并将其移动到第二个线程的 class。
理想情况下,我想做这样的事情:
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引擎的方法?
QObject
与父 QObject
的线程或当前线程(如果它们没有父线程)具有线程关联。在您的示例中,很可能在 MyQtQuickClass
的实例化期间创建的一些 QObject
与创建它们的线程具有亲和力。在 GUIthread
中创建 MyQtQuickClass
可以解决这个问题。
但是,所有Qt windows 必须 运行与QGuiApplication
在同一个线程中,如果您尝试,您的应用程序很可能会崩溃。
如果您希望 QQuickView 位于 main()
线程之外,那么您必须:
- 创建一个新的
std::thread
(不是QThread
,因为它是QObject
,所以不能在您的QGuiApplication
之前创建) - 运行 该线程中的一个
init()
函数。让它实例化您的QGuiApplication
并启动事件循环。 - 也在该线程中创建您的
QQuickView
。 - 确保仅从该线程访问所有 GUI 对象。
- 确保您的
main()
线程在您的QGuiApplication
在您的其他线程中创建之前不会创建任何QObject
。
有关详细信息,请参阅 How to avoid Qt app.exec() blocking main thread。