自学内容网 自学内容网

【QML】QML多线程应用(WorkerScript)

1. 实现功能

QML项目中,点击一个按键后,运行一段比较耗时的程序,此时ui线程会卡住。如何避免ui线程卡住。

2. 单线程(会卡住)

2.1 界面

在这里插入图片描述

2.2 现象

  • 点击delay btn后,执行耗时函数(TestJs.func_delay())界面阻塞(阻塞了12s),等待运行完成后,点击ui btn才能响应。
qml: 2024-11-14 09:48:29 ui thread
qml: 2024-11-14 09:48:30 click delay btn
qml: delay thread 2024-11-14 09:48:42
qml: 2024-11-14 09:48:42 ui thread

2.3 main.qml

import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.15
import "test.js" as TestJs

Window {
    width: 640
    height: 480
    visible: true
    title: qsTr("Thread")

    Row{
        spacing: 20

        Button{
            width: 200
            height: 100
            text: "ui btn"

            onClicked: {
                console.log(Qt.formatDateTime(new Date(), "yyyy-MM-dd HH:mm:ss"), "ui thread")
            }
        }

        Button{
            width: 200
            height: 100
            text: "delay btn"

            onClicked: {
console.log(Qt.formatDateTime(new Date(), "yyyy-MM-dd HH:mm:ss"), "click delay btn")
                TestJs.func_delay()
            }
        }
    }
}

2.4 test.js


//耗时函数
function func_delay() {
    var cnt = 0;
    for(let i=0; i<1000000000; i++){
        cnt++;
    }
    console.log("delay thread", Qt.formatDateTime(new Date(),"yyyy-MM-dd HH:mm:ss"))
}

3. 多线程(WorkerScript方式)

3.1 界面

在这里插入图片描述

3.2 现象

  • 将耗时函数(func_delay())放到WorkerScript.onMessage中执行,这样ui线程不会阻塞。
  • ui线程与delay线程直接可以通讯,发送通过sendMessage,接收通过onMessage
qml: 2024-11-14 09:54:11 ui thread
qml: 2024-11-14 09:54:11 click delay btn-1
qml: 2024-11-14 09:54:11 click delay btn-2
qml: 2024-11-14 09:54:12 ui thread
qml: 2024-11-14 09:54:13 ui thread
js: delay thread 2024-11-14 09:54:23
js: ui thread -> delay thread:  Hello, I am ui thread.
qml: delay thread -> ui thread:  Hello, I am delay thread.

3.3 main.qml

import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.15
import "test.js" as TestJs

Window {
    width: 640
    height: 480
    visible: true
    title: qsTr("Thread")

    Row{
        spacing: 20

        Button{
            width: 200
            height: 100
            text: "ui btn"

            onClicked: {
                console.log(Qt.formatDateTime(new Date(), "yyyy-MM-dd HH:mm:ss"), "ui thread")
            }
        }

        Button{
            width: 200
            height: 100
            text: "delay btn"

            onClicked: {
                console.log(Qt.formatDateTime(new Date(), "yyyy-MM-dd HH:mm:ss"), "click delay btn-1")

//发送数据
                myWorker.sendMessage({'msg': 'Hello, I am ui thread.'})

console.log(Qt.formatDateTime(new Date(), "yyyy-MM-dd HH:mm:ss"), "click delay btn-2")
            }
        }

        WorkerScript{
            id: myWorker
            source: "test.js"

//接收数据
            onMessage: {
                console.log("delay thread -> ui thread: ", messageObject.msg)
            }
        }
    }
}

3.4 test.js


function func_delay() {
    var cnt = 0;
    for(let i=0; i<1000000000; i++){
        cnt++;
    }
    console.log("delay thread", Qt.formatDateTime(new Date(),"yyyy-MM-dd HH:mm:ss"))
}


WorkerScript.onMessage = function(message){
    func_delay()
    console.log("ui thread -> delay thread: ", message.msg)

//发送数据
    WorkerScript.sendMessage({'msg': 'Hello, I am delay thread.'})
}



参考

Qt 之 qml WorkerScript使用


原文地址:https://blog.csdn.net/yangshuoSB/article/details/143758903

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!