如何以不阻塞UI的方式执行其他组件所需的时间太长的功能 [英] How to execute functions of other components that take too long to execute in a way that doesn't block UI

查看:82
本文介绍了如何以不阻塞UI的方式执行其他组件所需的时间太长的功能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我要从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的方式执行其他组件所需的时间太长的功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆