qml c++ 多线程属性绑定

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生活在guiThreadSerialConnection生活中routerThread。和(没有 qml)
之间的信号和槽可以工作,因为它们在默认情况下被 qt 作为异步处理。(只要定义了适当的类型。)RouterGui

Tei*_*mpz 4

好吧,不,您无法从 GUI 访问线程对象,也不应该尝试这样做。

您需要构建一个位于暴露给 qml 的主线程中的 C++ 模型。在此模型中,您可以通过排队连接连接到线程发出的信号,并将它们链接到模型自己的信号。此外,您还应该确保当您从另一个线程拥有的对象读取数据时,所有内容都已正确互斥,否则您将读取垃圾。