Dav*_*ijn 5 c++ qt multithreading qml
我正在创建一个模块化应用程序。它有一个Core, 和一些模块,其中有一个 gui 模块。这些模块可以通过命令行启动:
myApp gui=qml=qmlFile.qml connection=serial=/dev/ttyS1
Run Code Online (Sandbox Code Playgroud)
将使用一个(也可以使用多个)gui 和一个串行连接启动应用程序。总是有一个Router对象来处理连接。Guis 是由一个看起来像这样的类加载的:
class Gui :QObject{
Core* core;
public:
QQmlApplicationEngine engine;
public slots:
void start(){
engine.load("qrc:/gui/from/command/line.qml");
}
Run Code Online (Sandbox Code Playgroud)
在 gui 中,我有一个很好的 qml 称为ConnectionController{}添加/删除连接的简单方法。但这只是同类中的第一个:最终每个模块都应该有一个 qml 组件来控制它。
这一切正常,但现在我正在尝试添加多个线程。我想要一个RouterThread和一个GuiThread。这本身只是将Router(由Core)的创建更改为:
m_router = new Router(this /*not as parent, just as pointer*/);
m_router->moveToThread(&routerThread);
Run Code Online (Sandbox Code Playgroud)
(gui 现在仍然存在于主线程中)在此之后,除了 qml 属性绑定之外,一切仍然正常。
QQmlEngine: Illegal attempt to connect to SerialConnection(0x7f58d00013a0) that is in a different thread than the QML engine
Run Code Online (Sandbox Code Playgroud)
因为Gui它的孩子QQmlEngine engine生活在guiThread而SerialConnection生活中routerThread。和(没有 qml)
之间的信号和槽可以工作,因为它们在默认情况下被 qt 作为异步处理。(只要定义了适当的类型。)RouterGui
好吧,不,您无法从 GUI 访问线程对象,也不应该尝试这样做。
您需要构建一个位于暴露给 qml 的主线程中的 C++ 模型。在此模型中,您可以通过排队连接连接到线程发出的信号,并将它们链接到模型自己的信号。此外,您还应该确保当您从另一个线程拥有的对象读取数据时,所有内容都已正确互斥,否则您将读取垃圾。