Qt5 official demo consumer set 32 -- QT quick examples-threading

Source: Internet
Author: User
Tags dataloader

All articles in this series can be viewed here in http://blog.csdn.net/cloud_castle/article/category/2123873

Link to qt5 official demo release set 31 -- stocqt


Because the qml thread is involved in this example, it is found that it belongs to the QT quick example series. There are 19 demos in this series, covering multiple elements in QT quick. If you are free, let's take an article in this series. I believe this is a great journey ~


Well, when writing applications, especially User Interface programs, multithreading is often a topic that cannot be avoided. It takes more than 3 seconds for the to die. It is estimated that many users plan to CTRL + ALT + Delete...

Therefore, QT also facilitates the compilation of multithreading. In widgets, we usually use qthread to complete multithreading. What about qml that emphasizes user experience, I have to mention workerscript.

Workscript contains an Attribute source to declare a JS file, which is used to open up a new thread to process those time-consuming computations. For more details, refer to manual.


Running the program is a familiar selection interface:



1) threaded listmodel

This example is simple and describes how to use workscript to update the listmodel in a new thread.



The program consists of two files:

Timedisplay. qml:

Import qtquick 2.0 rectangle {color: "white" width: 200 Height: 300 listview {anchors. fill: parent Model: listmodel delegate: component {text: Time }}listmodel {ID: listmodel} workerscript {ID: worker Source: "dataloader. JS "// declare JS processing functions }//! [0] timer {// 2 seconds interval timer ID: timer interval: 2000; repeat: true running: True triggeredonstart: True ontriggered: {var MSG = {'action ': 'appendcurrenttime', 'model': listmodel}; // here, the listmodel object is used as the parameter of sendmessage (). worker is not allowed for other qobject object types. sendmessage (MSG); // call sendmessage () to run the computing of workerscript }}//! [0]}

Dataloader. JS:

//! [0] workerscript. onmessage = function (MSG) {// The format of the processing function is as follows: workerscript. onmessage = function ().... if (MSG. action = 'appendcurrenttime') {var DATA = {'time': new date (). totimestring ()}; MSG. model. append (data); // note that the model here declares MSG by the msg parameter. model. sync (); // This function is designed for workscript and is used to save workscript modifications to listmodel }}//! [0]


The above is the implementation of a basic workscript. Here is a slightly more complex example:

2) worderscript

This example uses multithreading to calculate Pascal's triangle in the background, and intentionally uses an algorithm that is not very optimized (which can be directly obtained through the binary model, I don't quite remember), so that we can understand the background computing and the interface is still responsive.

As for what is Pascal's triangle, I'm sure you will not be unfamiliar with it. In fact, it is what we mean by Yang Hui's triangle:


That is to say, the value of each small square is equal to the sum of the values of the two squares above it.

In our program, the number of layers in the square is 64 layers. If we use this accumulate method to obtain the value of any square, it is naturally a relatively time-consuming operation.

First, let's look at the running effect:



As you can see, when I select the square of 54th rows and 41 columns, the result below becomes "loading... ", but the interface is not stuck, we can still move back or choose a new square.

Workerscript. qml:

Import qtquick 2.0 rectangle {width: 320; Height: 480 //! [1] workerscript {ID: myworker Source: "workerscript. JS "onmessage: {// note that this onmessage is different from the onmessage in JS. Here it is used to update the interface display, instead of executing the computation. Similar to the signal slot, it responds to the 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 {// custom spinner Control ID: rowspinner label: "row" onvaluechanged: {// call the thread function resulttext to change the value. 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); // a two-dimensional array of 64 X for (VAR I = 0; I <64; I ++) cache [I] = new array (64); function triangle (row, column) {// define the validity of the columns of the triangle function. If (Cache [row] [column]) // if the value of this square is calculated in the cache, return return cache [row] [column] If (column <0 | column> row) // The number of rows must be greater than or equal to the number of columns return-1; if (column = 0 | column = row) // the left and right sides are both 1 return 1; Return Triangle (Row-1, column-1) + triangle (Row-1, column); // otherwise, this function is called recursively to calculate the square value }//! [0] workerscript. onmessage = function (Message) {// calculate result (may take a while, using a naive algorithm) // original note: it may take some time, because a naive algorithm is used ~ VaR calculatedresult = triangle (message. row, message. column); // send result back to main thread workerscript. sendmessage ({row: Message. row, // similar to the signal slot, the returned data responds to column: Message in onmessage of workerscript. column, result: calculatedresult });}//! [0]


Finally, the implementation of the spinner is pasted, because QT quick controls does not seem to provide similar controls. If you want to design similar controls, refer ~ :
Spinner. qml:

import QtQuick 2.0Rectangle {    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" }            }        }    }}


Qt5 official demo consumer set 32 -- QT quick examples-threading

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.