如何在主线程外创建QtQuick窗口
我想要的是一个主线程,它实例化一个扩展 QQuickView 的类并将其移动到第二个线程.
What I'd like to have is a main thread that instantiates a class that extends QQuickView and moves it to a second thread.
理想情况下,我想做这样的事情:
Ideally, I would like to do something like this:
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).
With something like this I get this error: QQmlEngine: Illegal attempt to connect to QQmlContext(0x120fc60) that is in a different thread than the QML engine QQmlEngine(0xdf6e70).
有解决方法吗?或者直接在第二个线程中创建QML引擎的方法?
Is there a workaround? Or a way to create the QML engine directly in the second thread?
如果你想让 QQuickView 存在于 main()
线程之外,那么你必须:
If you want a QQuickView to live outside the main()
thread, then you must:
- 创建一个新的
std::thread
(不是QThread
,因为它是一个QObject
,所以它不能在你之前创建QGuiApplication
) - 在该线程中运行
init()
函数.让它实例化您的QGuiApplication
并启动事件循环. - 也在该线程中创建您的
QQuickView
. - 确保仅从该线程访问所有 GUI 对象.
- 确保您的
main()
线程在您的QGuiApplication
在其他线程中创建之前不会创建任何QObject
.
- Create a new
std::thread
(NOT aQThread
, because it is aQObject
so it mustn't be created before yourQGuiApplication
) - Run an
init()
function in that thread. Let it instantiate yourQGuiApplication
and start the event loop. - Create your
QQuickView
in that thread too. - Ensure that all of your GUI objects are accessed from that thread only.
- Ensure that your
main()
thread doesn't create anyQObject
s until after yourQGuiApplication
has been created in your other thread.
请参阅如何避免使用 Qt 应用.exec() 阻塞主线程了解更多详情.