原文:https://doc.qt.io/qt-5/qml-qtqml-workerscript-workerscript.html
实现Qt Quick应用中使用线程
导入声明:import QtQml.WorkerScript 2.15
属性:
- ready: bool
- source: url
信号:
- message (jsobject msg)
方法:
- sendMessage (jsobject message)
详细描述:
在一个新的线程中使用WorkerScript执行操作。这有利于不阻断主GUI线程,并在后台运行操作。
信息可以在线程间传递。父线程用sendMessage(),新线程用onMessage()处理接收。
一个例子:
import QtQuick 2.0
Rectangle {
width: 300; height: 300
Text {
id: myText
text: 'Click anywhere'
}
WorkerScript {
id: myWorker
source: 'script.mjs'
onMessage: myText.text = messageObject.reply
}
MouseArea {
anchors.fill: parent
onClicked: myWorker.sendMessage({ 'x': mouse.x, 'y': mouse.y })
}
}
上面的worker script 指定了一个 JavaScript 文件——“script.mjs”。用于在新线程中执行操作。
下面是 script.mjs:
WorkerScript.onMessage = function(message) {
// ... 在这里完成需要很长时间的运行和操作
WorkerScript.sendMessage({ 'reply': 'Mouse is at ' + message.x ',' + message.y})
}
当用户点击Rectangede 任意位置,sendMessage()函数会被调用。触发script.mjs中的 WorkerScript.onMessage()处理程序。script.mjs中的WorkerScript.onMessage()又发送一个回应信息,最后被myWorker的onMessage()处理程序接收到。
这个例子使用的是ECMAScript模式的脚本文件,因为后缀名是.mjs。它可以使用import声明,导入其他模块,访问其他模块的函数功能,并且在严格模式下运行。
如果使用后缀名为.js的附加脚本,那么就是一个纯JavaScript声明文件,并且非严格模式执行。
注意:每一个WorkerScript 元素都会实例化一个单独的JavaScript引擎来确保完全的隔离性和线程安全。如果这种机制对你的运行环境造成过高的内存消耗,可以考虑共享WorkerScript元素。
限制条件:
因为WorkerScript.onMessage()函数是在一个独立的线程中执行,所以JavaScript文件是与主QML引擎完全剥离的上下文中评估检测的。这意味着不像被引入QML的普通JavaScript文件。上例中的script.mjs不能访问QML中的属性,方法或其他属性,也不能通过QQmlContext访问任何OML对象上下文中的属性。
此外,附加的JS脚本参数传递的参数类型也是有限制的。详情查阅下面的方法文档中sendMessage详细说明。
如果附加脚本是一个纯的JavaScript脚本,不可以使用.import语法。相反,符合ECMAScript模式的脚本可以自由的使用import和export声明。
详情查阅Qt Quick Examples - Threading 和 Threaded ListModel Example.
属性文档:
ready: bool
保存WorkerScript是否已经实例化,并准备通过WorkerScript.sendMessage()接收信息。
source: url
保存实现WorkerScript.onMessage()处理线程操作的附加JavaScript文件地址。
如果url中的文件名组成以".mjs"为后缀,说明脚本已经设置为严格模式并符合ECMAScript标准。否则只是一个简单脚本。
信号文档:
message (jsobject msg)
从另一个线程中的工作脚本接收到消息msg时,就会调用sendMessage()发射信号。
注意:对应的处理程序是onMessage。
方法文档:
sendMessage (jsobject message)
向另一个线程中的工作脚本发送已经初始化的message。另一个线程中的工作脚本可以通过onMessage()处理器接收此message。
message对象只能包含下面类型的值:
- boolean, number, string
- JavaScript 对象 和 数组
- ListModel 对象(不允许任何其他QObject*类型)
所有对象和数组都会拷贝给message。除了ListModel对象以外,其他参数在传递过程中,另一个线程中的任何修改,都不会污染原始数据。