本文介绍了Qt/QML前端与另一个线程中的C++后端/模型直接交互的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Qt/QML(Qt5.7.1)应用程序,它需要与位于另一个线程中的(相当复杂的)C++后端交互。

目前,我按照博客文章https://mayaposch.wordpress.com/2011/11/01/how-to-really-truly-use-qthreads-the-full-explanation/中的建议创建了一个C++类"MainController",通过

注册
qmlRegisterType<MainController>("MainController", 1, 0, "MainController");

,并从主QML文件实例化,如下所示:

ApplicationWindow {
    MainController {
        id: mainController
    }

    ...
}

在其构造函数中,MainController(与QML代码运行在同一线程中)创建一个Worker对象,然后将其移动到自己的线程中:

MainController::MainController() : QObject()
{
    state = GUI_State::HW_STANDBY;

    QThread* thread = new QThread;
    Worker* worker = new Worker();
    worker->moveToThread(thread);
    connect(worker, SIGNAL (error(QString)), this, SLOT (errorString(QString)));
    connect(thread, SIGNAL (started()), worker, SLOT (process()));
    connect(worker, SIGNAL (finished()), thread, SLOT (quit()));
    connect(worker, SIGNAL (finished()), worker, SLOT (deleteLater()));
    connect(thread, SIGNAL (finished()), thread, SLOT (deleteLater()));
    ...
    thread->start();
    qDebug() << "Thread started";
}

现在,我可以通过以下方式使用信号进行通信:

QML -> MainController -> Worker
QML <- MainController <- Worker
但是这样做有很多开销:要使工作进程的"属性"对GUI可用,我必须向MainController发送一个信号,它需要一个插槽来接收信号,然后触发另一个信号,然后可以从QML代码中接收该信号。同样适用于另一个方向。

如何在后端(Worker类)和QML层之间建立直接链接,同时保留双线程架构?

qml

如果您不使用Q_PROPERTY,您可以在推荐答案中实例化工作器本身,还可以通过

使您的工作器实例成为上下文属性
Worker* workerObj = new Worker();
engine->rootContext()->setContextProperty("qmlWorker", workerObj );

这仅适用于信号/插槽连接以及Q_INVOKABLE

如果您希望通过不同的线程使用QML-Properties,我建议您使用您的方法,因为这通常是在Qt中处理线程的一种节省方式。

这篇关于Qt/QML前端与另一个线程中的C++后端/模型直接交互的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

05-16 11:23