在QML上下文中将QThread与信号/插槽一起使用

时间:2018-12-12 14:29:29

标签: c++ qt qml qthread

请查看以下(有效)示例。

我的问题很简单:

  • 我可以在Qml上下文中正确使用QThread吗?
  • 这是从Qml与QThread进行通信(反之亦然)的一种保存方式吗?

如果将WorkerThread扩展为执行繁重的工作或执行可能会阻止的操作,则我想确保我的ui线程在任何情况下都不会冻结。

main.qml

import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Controls 2.0

Window {
    id: window
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

    Connections {
        target: window.visible ? _qWorkerThreadController : null

        onResponseToQml: {
            t.text = response;
        }
    }

    Timer {
        id: timer
        interval: 1000
        repeat: false
        triggeredOnStart: false

        onTriggered: {
            _qWorkerThreadController.methodCallQml("test");
        }
    }

    Rectangle {
        width: 200
        height: 200
        color: "green"
        anchors.centerIn: parent
        Label {
            id: t
            color: "red"
            height: 20
            width: 50
            anchors.centerIn: parent
        }
    }

    Component.onCompleted: {
        timer.start();
    }
}

workerthread.cpp

#include "workerthread.h"


WorkerThread::WorkerThread(QObject *parent) :
    QObject(parent)
{

}

void WorkerThread::methodCallSlot(QString s) {
    // do Some work with 's'
    QMetaObject::invokeMethod(this->m_caller, "methodCallQmlResponse", Qt::QueuedConnection, Q_ARG(QString, s));
}

void WorkerThread::setCaller(QObject *caller) {
    this->m_caller = caller;
}

workerthreadcontroller.cpp

#include "workerthreadcontroller.h"
#include "workerthread.h"

#include <QThread>
#include <QDebug>

WorkerThreadController::WorkerThreadController(QObject *parent) :
    QObject(parent)
{
    WorkerThread *worker = new WorkerThread();
    this->m_workerThread = worker;
    QThread *t = new QThread();
    worker->moveToThread(t);
    connect(t, &QThread::finished, t, &QThread::deleteLater);
    connect(t, &QThread::started, this, [=]() { m_workerThread->setCaller(this);});
    connect(m_workerThread, &WorkerThread::methodCallSignal, m_workerThread, &WorkerThread::methodCallSlot);
    t->start();
}

void WorkerThreadController::methodCallQml(QString s) {
    qDebug() << s;
    emit m_workerThread->methodCallSignal(s);
}

void WorkerThreadController::methodCallQmlResponse(QString s) {
    emit responseToQml(s);
}

main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include "workerthreadcontroller.h"

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

    QGuiApplication app(argc, argv);

    QQmlApplicationEngine engine;

    WorkerThreadController workerThreadController;
    engine.rootContext()->setContextProperty("_qWorkerThreadController", &workerThreadController);
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));

    return app.exec();
}

0 个答案:

没有答案