首页 > 解决方案 > 通过 GUI 线程进行的更改不会反映在 workerscript 中

问题描述

在下面的代码中,listmodel 在线程之间共享,并且设置了一个计时器来更新模型的值,这些更改应该在 workerscript ( docs ) 中反映(期望的行为)。但在 workerscript 中,它始终是初始值,因为它不知道数据已更改。

// 主文件

    Window {
    id: window
    visible: true
    width: 150
    height: 200
    title: qsTr("Hello Testing")

    DataModel {
        id: model
    }

    Timer {
        interval: 1000
        running: true
        repeat: true
        onTriggered: {
            model.setProperty(0, 'datum', new Date().toLocaleString())
        }
    }

    WorkerScript {
        id: bgScript
        source: "script.js"

    }

    Timer {
        interval: 1000
        running: true
        repeat: true
        onTriggered: {
            bgScript.sendMessage({'model': model})
        }
    }

    Text {
        id: datum
        text: qsTr(model.get(0).datum)
    }

}

// 工人脚本

WorkerScript.onMessage = function (arg) {
    console.log(arg.model.get(0).datum)   // value is "Date Time" on every call
}

// 模型

ListModel {

    ListElement {
        datum: "Date Time"
    }


}

标签: qtqml

解决方案


您将模型复制到 JS 对象中,并将该对象传递给 JS 函数。您将永远不会从 JS 函数中收到类似对象的更新通知。绑定仅适用于 QML 属性,不适用于 JS 值。

但即使这在一般情况下确实有效,它仍然无法在WorkerScript. 根据文档,WorkerScript js 文件无权访问调用 QML 的属性。

由于 WorkerScript.onMessage() 函数在单独的线程中运行,因此 JavaScript 文件在与主 QML 引擎不同的上下文中进行评估。这意味着与导入QML的普通JavaScript文件不同,上例中的script.mjs不能访问QML项的属性、方法或其他属性,也不能通过QQmlContext访问QML对象上设置的任何上下文属性.


推荐阅读