<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                本系列所有文章可以在這里查看[http://blog.csdn.net/cloud_castle/article/category/2123873](http://blog.csdn.net/cloud_castle/article/category/2123873) 接上文[Qt5官方demo解析集31——StocQt](http://blog.csdn.net/cloud_castle/article/details/38258159) 因為涉及到QML線程看到這個例子,發現它是屬于Qt Quick Example這個系列的。這個系列共有19個demo,涵蓋了Qt Quick中多種元素,有空我們把這個系列一篇篇做下來,相信是一趟不錯的旅途~ 好了,在我們編寫應用程序,尤其是用戶界面程序,多線程往往是避不開的一個話題。界面卡死超過3秒,估計許多用戶就打算Ctrl+Alt+Delete了... 那么Qt當然也為我們編寫多線程提供了便利,在Widgets中呢我們通常使用QThread來完成多線程,那對于更強調用戶體驗的QML而言呢,就不得不提到WorkerScript了。 WorkScript 包含了一個屬性source來聲明一個js文件,用來開辟一個新的線程以處理那些耗時的計算。更詳細的介紹,大家可以查看Manual。 程序運行起來是我們熟悉的選擇界面: ![](https://box.kancloud.cn/2016-01-18_569cbd097f3c8.jpg) 1)Threaded ListModel 這個例子比較簡單,介紹了如何使用WorkScript 在一個新的線程中更新ListModel。 ![](https://box.kancloud.cn/2016-01-18_569cbd098b686.jpg) 程序由兩個文件構成: timedisplay.qml: ~~~ import QtQuick 2.0 Rectangle { color: "white" width: 200 height: 300 ListView { anchors.fill: parent model: listModel delegate: Component { Text { text: time } } ListModel { id: listModel } WorkerScript { id: worker source: "dataloader.js" // 聲明js處理函數 } // ![0] Timer { // 2秒間隔定時器 id: timer interval: 2000; repeat: true running: true triggeredOnStart: true onTriggered: { var msg = {'action': 'appendCurrentTime', 'model': listModel}; // 這里將ListModel對象作為sendMessage()的參數,除此以外,其他QObject對象類型都不被允許 worker.sendMessage(msg); // 調用sendMessage()運行WorkerScript的計算 } } // ![0] } } ~~~ dataloader.js: ~~~ // ![0] WorkerScript.onMessage = function(msg) { // 處理函數的格式如下WorkerScript.onMessage = function().... if (msg.action == 'appendCurrentTime') { var data = {'time': new Date().toTimeString()}; msg.model.append(data); // 注意到這里的model由msg參數聲明 msg.model.sync(); // 該函數專為WorkScript而生,用來保存WorkScript對ListModel的修改 } } // ![0] ~~~ 以上就是一個基本的WorkScript的實現,下面來看一個稍微復雜一點的例子: 2)WorderScript 這個例子使用了多線程在后臺計算帕斯卡三角形(Pascal's Triangle),并且有意采用了一種并非很優化的算法(通過二項式好像可以直接求,我不太記得了),使得我們可以體會到后臺計算而界面依然保持響應的效果。 至于什么是Pascal's Triangle,我放張圖想必大家不會陌生,其實它就是我們說的楊輝三角: ![](https://box.kancloud.cn/2016-01-18_569cbd099a1e6.jpg) 也就是說,每個小方格的值等于其上面兩個方格數值之和。 而在我們這個程序中,方格的層數為64層,如果是使用這種累加的方法到得到任意一個方格的值,自然是一個比較費時的操作。 先看下運行效果: ![](https://box.kancloud.cn/2016-01-18_569cbd09b6071.jpg) 可以看到,當我選擇了第54行,41列的方格時,下方的結果變成了"Loading...",但界面并沒有卡死,我們依然可以后退,或是選擇新的方格。 workerscript.qml: ~~~ import QtQuick 2.0 Rectangle { width: 320; height: 480 //! [1] WorkerScript { id: myWorker source: "workerscript.js" onMessage: { // 注意到這個的onMessage與js中的onMessage不同,這里用來更新界面顯示,而非執行計算,類似信號槽,響應js中的sendMessage if (messageObject.row == rowSpinner.value && messageObject.column == columnSpinner.value){ //Not an old result if (messageObject.result == -1) resultText.text = "Column must be <= Row"; else resultText.text = messageObject.result; } } } //! [1] Row { y: 24 spacing: 24 anchors.horizontalCenter: parent.horizontalCenter //! [0] Spinner { // 自定義的Spinner控件 id: rowSpinner label: "Row" onValueChanged: { // 值改變調用線程函數 resultText.text = "Loading..."; myWorker.sendMessage( { row: rowSpinner.value, column: columnSpinner.value } ); } } //! [0] Spinner { id: columnSpinner label: "Column" onValueChanged: { resultText.text = "Loading..."; myWorker.sendMessage( { row: rowSpinner.value, column: columnSpinner.value } ); } } } Text { id: resultText y: 180 width: parent.width horizontalAlignment: Text.AlignHCenter wrapMode: Text.WordWrap font.pixelSize: 32 } Text { text: "Pascal's Triangle Calculator" anchors { horizontalCenter: parent.horizontalCenter; bottom: parent.bottom; bottomMargin: 50 } } } ~~~ workerscript.js: ~~~ //Will be initialized when WorkerScript{} is instantiated var cache = new Array(64); // 64x64 的二維數組 for (var i = 0; i < 64; i++) cache[i] = new Array(64); function triangle(row, column) { // 定義函數triangle行列的合法性 if (cache[row][column]) // 如果緩存中計算過該方格的值,直接返回 return cache[row][column] if (column < 0 || column > row) // 行數必須大于等于列數 return -1; if (column == 0 || column == row) // 左右兩側值均為 1 return 1; return triangle(row-1, column-1) + triangle(row-1, column); // 否則遞歸調用該函數計算方格數值 } //! [0] WorkerScript.onMessage = function(message) { //Calculate result (may take a while, using a naive algorithm) // 原注:可能會花點時間噢,因為使用了一個天真的算法~ var calculatedResult = triangle(message.row, message.column); //Send result back to main thread WorkerScript.sendMessage( { row: message.row, // 類似信號槽,返回數據在WorkerScript中的onMessage中響應 column: message.column, result: calculatedResult} ); } //! [0] ~~~ 最后貼出Spinner的實現,因為Qt Quick Controls似乎沒有提供類似控件,如果要設計類似的控件可以參考~: Spinner.qml: ~~~ import QtQuick 2.0 Rectangle { width: 64 height: 64 property alias value: list.currentIndex property alias label: caption.text Text { id: caption text: "Spinner" anchors.horizontalCenter: parent.horizontalCenter } Rectangle { anchors.top: caption.bottom anchors.topMargin: 4 anchors.horizontalCenter: parent.horizontalCenter height: 48 width: 32 color: "black" ListView { id: list anchors.fill: parent highlightRangeMode: ListView.StrictlyEnforceRange preferredHighlightBegin: height/3 preferredHighlightEnd: height/3 clip: true model: 64 delegate: Text { font.pixelSize: 18; color: "white"; text: index; anchors.horizontalCenter: parent.horizontalCenter } } Rectangle { anchors.fill: parent gradient: Gradient { GradientStop { position: 0.0; color: "#FF000000" } GradientStop { position: 0.2; color: "#00000000" } GradientStop { position: 0.8; color: "#00000000" } GradientStop { position: 1.0; color: "#FF000000" } } } } } ~~~
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看