• qml demo分析(threading-线程任务)


    一、关键类说明

      qml内置了WorkerScript组件,该组件有一个source属性,可以加载js文件,含有一个名为message的信号,意味着他有一个默认的onMessage槽函数,除此之外他还有一个方法,通过该方法可以给js文件中名为WorkerScript.onMessage的方法(在工作线程执行)发送消息,在次接收消息的函数体内部可以通过 WorkerScript.sendMessage的方式在发送消息给WorkerScript内置槽(在主线程执行),WorkerScript类的详细说明如图1所示

    图1 WorkerScript说明

    二、示例效果分析

      该示例程序总共包含2个简单的WorkerScript使用方法,分别应用于timedisplay.qml组件和workerscript.qml组件

    1、更新视图数据

      如图2所示,是一个WorkerScript的简单使用,qml文件通过WorkerScript对象向js函数发送一个消息,js函数中更新视图内容,消息发送流程:ui线程->工作线程处理(调用接口更新ui)

    图2 更新视图数据

      视图ui文件内容如下,每个2秒钟timer定时器就会触发,通过worker.sendMessage发送消息给js函数,这个js文件是通过WorkerScript对象的source指定,如下第17行代码所示

     1 Rectangle {
     2     color: "white"
     3      200
     4     height: 300
     5 
     6     ListView {
     7         anchors.fill: parent
     8         model: listModel
     9         delegate: Component {
    10             Text { text: time }
    11         }
    12 
    13         ListModel { id: listModel }
    14 
    15         WorkerScript {//在新线程执行操作,不阻塞ui线程,在父线程使用sendMessage发送消息 在子线程使用onMessage处理
    16             id: worker
    17             source: "dataloader.js" //加载js文件
    18         }
    19 
    20 // ![0]
    21         Timer {
    22             id: timer
    23             interval: 2000; 
    24             repeat: true
    25             running: true
    26             triggeredOnStart: true//定时器开始执行一次   默认该值为false 定时器开始不执行 等过interval后才执行
    27 
    28             onTriggered: {
    29                 var msg = {'action': 'appendCurrentTime', 'model': listModel};
    30                 worker.sendMessage(msg);//在新线程里执行该操作 不阻塞ui线程 
    31             }
    32         }
    33 // ![0]
    34     }
    35 }

      对应的js文件dataloader.js比较简单,就一个函数,代码如下

    1 WorkerScript.onMessage = function(msg) {
    2     if (msg.action == 'appendCurrentTime') {//如果是指定动作 
    3         var data = {'time': new Date().toTimeString()};//获取当前时间
    4         msg.model.append(data);//list添加新数据
    5         msg.model.sync();   // 更新数据到ui
    6     }
    7 }

    2、滚轮游戏

      如图3所示,是WorkerScript的一个更复杂的使用,就行文章开头说的那样,消息发送流程:ui线程->工作线程处理->ui线程

    图3 滚轮游戏

      滚轮游戏的代码比较简单,在这里我就贴主要部分

     1 WorkerScript {
     2         id: myWorker
     3         source: "workerscript.js"//指定js文件
     4 
     5         onMessage: {//接收js文件发送的sendMessage消息
     6             if (messageObject.row == rowSpinner.value && messageObject.column == columnSpinner.value){ //Not an old result
     7                 if (messageObject.result == -1)
     8                     resultText.text = "Column must be <= Row";
     9                 else
    10                     resultText.text = messageObject.result;
    11             }
    12         }
    13     }
    14 //! [1]
    15     Row {//水平方向上的两个可以滚动的仪表框
    16         y: 24
    17         spacing: 24
    18         anchors.horizontalCenter: parent.horizontalCenter
    19 //! [0]
    20         Spinner {
    21             id: rowSpinner
    22             label: "Row"
    23             onValueChanged: {
    24                 resultText.text = "Loading...";
    25                 myWorker.sendMessage( { row: rowSpinner.value, column: columnSpinner.value } );
    26             }
    27         }
    28 //! [0]
    29 
    30         Spinner {
    31             id: columnSpinner
    32             label: "Column"
    33             onValueChanged: {
    34                 resultText.text = "Loading...";
    35                 myWorker.sendMessage( { row: rowSpinner.value, column: columnSpinner.value } );
    36             }
    37         }
    38     }

      其中Spinner是自己封装的一个组件,导出了当前文本和当前索引两个属性,对于的js文件如下

     1 var cache = new Array(64);
     2 for (var i = 0; i < 64; i++)
     3     cache[i] = new Array(64);
     4 
     5 function triangle(row, column) {
     6     if (cache[row][column])
     7         return cache[row][column]
     8     if (column < 0 || column > row)
     9         return -1;
    10     if (column == 0 || column == row)
    11         return 1;
    12     return triangle(row-1, column-1) + triangle(row-1, column);
    13 }
    14 //! [0]  
    15 WorkerScript.onMessage = function(message) {
    16     //Calculate result (may take a while, using a naive algorithm)
    17     var calculatedResult = triangle(message.row, message.column);
    18     //Send result back to main thread
    19     WorkerScript.sendMessage( { row: message.row,
    20                                 column: message.column,
    21                                 result: calculatedResult} );
    22 }
    23 //! [0]

      js文件就不多说了,本篇示例主要就是想分析下WorkerScript的使用,通过上边两种使用方式基本就能理解

  • 相关阅读:
    vue3父组件方法之间方法的互相调用
    vue3获取数据的注意点
    2021牛客暑期多校训练营5 D. Double Strings(DP/排列组合)
    2021牛客暑期多校训练营8 K. Yet Another Problem About Pi(几何)
    2021牛客暑期多校训练营8 D. OR(位运算/结论)
    2021牛客暑期多校训练营5 J. Jewels(二分图最大权匹配)
    关于C++ STL中对于set使用lower_bound进行二分查找的效率问题
    CSP202012-4 食材运输(70分)
    【k8s】Volume-pv-local
    【k8s】Volume-pvc
  • 原文地址:https://www.cnblogs.com/swarmbees/p/6568086.html
Copyright © 2020-2023  润新知