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     width: 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的使用,通過上邊兩種使用方式基本就能理解


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM