问题描述
我要从main.qml
调用其他组件中的函数,并以不阻塞UI线程的方式获取其结果.
From the main.qml
i want to call functions from other components and get their results in a way that doesn't block the UI thread.
获得这些函数的结果后,我想将它们放入公共"数组中.
After i have the results of these functions I want to push them into a "common" array.
如何使用QML?有什么可能的解决方案?
How can I do it with QML? What would be a possible solution?
我将在代码中说明我想做什么(我知道这永远行不通):
I'm going to illustrate in code what I want to do (I'm aware this would never work) :
main.qml
import QtQuick 2.0
import QtQuick.Controls 2.4
import QtQuick.Layouts 1.3
import AsyncWorker 1.0
ApplicationWindow {
id: window
title: "Stack"
visible: true
width: 600
height: 500
Page {
id: page
anchors {
fill: parent
margins: 10
}
ColumnLayout {
anchors.fill: parent
spacing: 10
RowLayout {
WorkerScript
{
id: importScanWorkerScript
source: "script.js"
onMessage: {
console.log(messageObject.data1)
console.log(messageObject.data2)
spinner.running = false;
}
}
BusyIndicator {
id: spinner
anchors.centerIn: parent
running: false
}
Panel1 {
id: panel1
}
Panel2 {
id: panel2
}
Button {
Layout.alignment: Qt.AlignHCenter
text: qsTr("Run asynchronous")
onClicked: {
spinner.running = true
//Is there a way to run the functions of the 2 panels in a workerscript??
importScanWorkerScript.sendMessage(panel1,panel2)
}
}
}
Item {
Layout.fillHeight: true
}
}
}
}
Panel1.qml
import QtQuick 2.0
import QtQuick.Controls 2.4
Item {
function info() {
var j=0
for(var i=0; i<99999999; i++) {
j+=i
}
return j
}
}
Panel2.qml
import QtQuick 2.0
import QtQuick.Controls 2.4
Item {
function info() {
var j=0
for(var i=0; i<1000000; i++) {
j+=i
}
return j
}
}
script.js
WorkerScript.onMessage = function(obj1,obj2) {
var obj1Test = obj1.info()//not working
var obj2Test = obj2.info()//not working
WorkerScript.sendMessage({ 'data1': obj1Test, "data2" : obj2Test })
}
推荐答案
我要发布我在评论中提到的示例:
I am posting an example of what I mentioned in the comments:
此示例运行一个计时器,该计时器在UI完好无损的情况下每秒在工作线程中发布调试消息.
This example runs a timer that posts a debug message every second in a worker thread while the UI is intact.
假设您有一个上班族.h:
Assume you have a class worker.h:
#include <QObject>
#include <QDebug>
#include <QTimer>
class Worker : public QObject {
Q_OBJECT
public:
explicit Worker(QObject* parent = nullptr): QObject(parent){
timer.setInterval(1000);
connect(&timer, &QTimer::timeout, [=]() {
qDebug() << "executing with wait";
});
}
~Worker(){}
Q_INVOKABLE void doSomeWork() { // modify this to accommodate your params
//do something here
timer.start();
}
private:
QTimer timer;
};
在main.cpp中将其定义为:
This is defined in main.cpp as:
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include "worker.h"
#include <QThread>
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
Worker cpp;
QThread cpp_thread;
cpp.moveToThread(&cpp_thread);
cpp_thread.start();
QQmlApplicationEngine engine;
engine.rootContext()->setContextProperty("cpp", &cpp);
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
return app.exec();
}
在您的QML中,您将其称为:
At some point in your QML you call it as:
WorkerScript.onMessage = function(obj1,obj2) {
cpp.doSomeWork() // modify this to accommodate your params
}
希望这会有所帮助.
这篇关于如何以不阻塞UI的方式执行其他组件所需的时间太长的功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!