【问题标题】:WorkerScript access to Controller classWorkerScript 访问 Controller 类
【发布时间】:2017-08-18 08:49:17
【问题描述】:

我有一个 BusyIndi​​cator,它应该在进行大量计算时旋转,并在计算完成时停止。

我认为 WorkerScript 是正确的方法,但是 from here,似乎 .js 文件中的辅助(计算线程)无权访问主 .qml 线程的对象。

这是有问题的,因为我所有的计算都是通过主线程实例化的控制器 C++ 定义的 QObject 执行的。

这是我的代码:

ma​​in.qml

import QtQuick 2.7
import QtQuick.Layouts 1.3
import QtQuick.Window 2.2
import QtQuick.Controls 2.2
import QtQuick.Controls.Material 2.0
import QtQuick.Controls.Styles 1.2
import QtQuick.Dialogs 1.2

import LcQml 1.0

ApplicationWindow
{
    id: window

    UiController
    {
        id: uiController
    }

    WorkerScript
    {
        id: importScanWorkerScript
        source: "importScanWorkerScript.js"
        onMessage:
        {
            busyIndicator.running = false;
        }
    }

    FileDialog
    {
        id: importScanDialog
        visible: false
        title: "Import a [scan] file"
        folder: "MyScannedScenesFolder"
        nameFilters: [ "STL files (*stl)" ]
        selectedNameFilter: "STL files (*stl)"
        onAccepted:
        {
            importScanWorkerScript.sendMessage({'filepath': importScanDialog.fileUrl})
            busyIndicator.running = true;
        }
    }

    BusyIndicator
    {
        id: busyIndicator
        running: false
        anchors.centerIn: parent
    }
}

importScanWorkerScript.js

WorkerScript.onMessage = function(message)
{
    uiController.onImportScanDevMenuClicked(message.filepath);
    WorkerScript.sendMessage()
}

Pb: uiController 未在 importScanWorkerScript.js 中定义。

我应该明白 WorkerScript 只能处理简单的情况吗?

【问题讨论】:

    标签: c++ qt qml qtquick2 qtquickcontrols2


    【解决方案1】:

    您已经注意到,WorkerScript 无法访问 UI 控件。但是您的单独线程可以使用消息与主 UI 线程“对话”。至于我,它的工作原理与所有其他语言/框架完全相同。每当您想更新 UI 或您的对象时,只需从线程发送一条消息。 例如:

    WorkerScript.onMessage = function(message) {
        WorkerScript.sendMessage({ 'action': 'start' })
        // do some heavy task here
        WorkerScript.sendMessage({ 'action': 'finish', 'data': somedata })
    }
    

    因此您的主要 qml 可能如下所示:

    WorkerScript {
        id: myWorker
        source: "func.js"
        onMessage: {
            switch(messageObject.action)
            {
            case 'start':
                spinner.running = true;
                uiController.doSomething();
                break;
            case 'finish':
                spinner.running = false;
                uiController.doSomethingAnother();
                break;
            }
        }
    }
    

    【讨论】:

    • 根据您的建议,uiController.doSomething() 和 uiController.doSomethingAnother() 在 UI 线程中处理,不是吗?就我而言,事实证明 uiController.doSomething() 和 uiController.doSomethingAnother() 是实际的繁重功能,应该是后台线程中的计算机......
    • 啊,好的,现在我明白了。这里最好的方法是在 C++ 代码中使用 QThread 运行繁重的任务。使用 Javascript 代码运行 C++ 任务是没有意义的,尽管您不能将对象传递给 WorkerScript。
    • 我不确定我是否理解 WorkerScript 文件对那时有用... 谁想在 js 中执行重度交换?无论如何,非常感谢您的帮助!
    猜你喜欢
    • 2017-12-02
    • 1970-01-01
    • 2012-05-01
    • 2018-03-21
    • 2022-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-24
    相关资源
    最近更新 更多