请查看以下(有效)示例。
我的问题很简单:
如果将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();
}