QT Demo Calqlatr (2) calqlatr.qml

Source: Internet
Author: User
Tags add numbers rewind

Import QtQuick 2.0import "content" import "Content/calculator.js" as Calcengine

Again, the most common import part we started with for QML code is not spared, but at least basic understanding and use.

In QML, if you need to use a system component, you must start the declaration. For custom components It is also necessary to import them at the beginning, and it is important to note that the system components are directly through the name, and for custom components, the "" package is required.

QML supports three types of import, namely:

    • Import component (Namespace): The mostcommon type of import is a module import. Clients can import QML modules which register QML object types and JavaScript resources into a given namespace.
    • Import directory: A directory which contains QML documents may also is imported directly in a QML document. This provides a simple-to-QML types to be segmented into reusable groupings:directories on the filesystem.
    • Import JS file:JavaScript resources May is imported directly in a QML document. Every JavaScript resource must has an identifier by which it is accessed.

Note: There are only three import JS, you must use as to specify a unique identifier, the other two kinds of optional.

CALQLATR.QML Code main structure

Rectangle {    Id:window    width:320    height:480    focus:true    color: "#272822"    onwidthchanged: Controller.reload ()    onHeightChanged:controller.reload ()    function operatorpressed (operator) { calcengine.operatorpressed (operator)}    function digitpressed (digit) {calcengine.digitpressed (digit)}    Item {}    Animationcontroller {}    Display {}}

The basic properties of id/width/height and color are needless to say, and have been used more than once in the previous sample code. The new property was focus, but we found that the program ran without any exceptions or differences, even if we changed the value of focus to false or removed the focus property (using the default value). This is only a description of the property that is not currently used in this example,TODO: We will learn the specific role of focus in the following.

Onwidthchanged and Onheightchanged

The following two lines are in the code:

    OnWidthChanged:controller.reload ()    onHeightChanged:controller.reload ()

The meaning is very well understood, that is, when width or height changes, call the Controller.reload () function to complete the UI redraw. But what makes me tangled is that the two event response functions of onwidthchanged and onheightchanged are defined there???

When I try to find these two functions or the signal of width and height through the help document, the result is not found. This time, I guess, it is also QT did some built-in processing but there is no documentation to explain things.

Is there a corresponding Onxxxchanged event response function for each property? Answer, yes. So, in addition to the onwidthchanged and onheightchanged functions above, there are a series of functions below:

    Onparentchanged:;    Onopacitychanged:;    Oncolorchanged:;    Onxchanged:;    Onychanged:;    Onvisiblechanged:;    Onfocuschanged:;

Of course, for the special property of ID, there is no corresponding onidchanged function.

digitpressed (digit) and operatorpressed (operator) functions

Next, two functions are defined:

    function operatorpressed (operator) {calcengine.operatorpressed (operator)}    function digitpressed (digit) { calcengine.digitpressed (Digit)}

In the previous article, "How to define and use functions in QML" is that we have learned how to define and invoke a function in qml, where the function body is also very simple, which is the corresponding function in the direct pass call content/calculator.js . But where are these two functions called to???

I'm looking for it, not in the current file, helpless use grep to find, found in button.qml the following function calls:

    Mousearea {        onclicked: {            if (operator)                window.operatorpressed (parent.text)            else                Window.digitpressed (Parent.text)        }    }

Inability to spit groove, but also the use of the cross-file object Id, this design and use of the system is a big thing will be a panic of the rhythm Ah.

Several other child elements

The following three sub-elements are available under the entire rectangle:

    • Item, number, and operator sections
    • Animationcontroller:ui initialization, as well as UI processing and animation parts when Width/height changes and drags to one of the following bars (a little bit around, actually, when the UI needs to be changed)
    • Display: The output part of the operation and the Grip control bar at the bottom, specifically implemented in the DISPLAY.QML file

Detailed analysis is carried out for each child element below.

Item section

    Item {        id:pad        width:180        numberpad {y:10; anchors.horizontalCenter:parent.horizontalCenter}    }

The width of item is specified in the code as 180, where the numbers and operators are partially encapsulated into a separate Numberpad QML document. It also specifies that the position of Numberpad in item is a coordinate of relative value 10, and the horizontal direction is centered relative to item (PS: The reader can change the value and alignment of this place by itself, and look at the effect of the respective operation).

Numberpad

Grid {    columns:3    columnspacing:32    rowspacing:16    button {text: "7"}    button {text: "8"}    Butto n {text: "9"} button {text:    "4"} button {text: "    5"} button {    text: "6"}    button {text: "1"}    B Utton {text: "2"} button {    text: "3"}    button {text: "0"}    button {text: "."}    button {text: "}    button {text:" ± "; Color: "#6da43d"; Operator:true}    Button {text: "?"; color: "#6da43d"; operator:true}    button {text: "+"; color: "#6da43d"; op Erator:true}    Button {text: "√"; color: "#6da43d"; operator:true}    button {text: "÷"; color: "#6da43d"; oper Ator:true}    Button {text: "x"; color: "#6da43d"; operator:true}    button {text: "C"; color: "#6da43d"; operat Or:true}    Button {text: ""; Color: "#6da43d"; Operator:true}    Button {text: "="; color: "#6da43d"; Operator:true}}

Open the Numberpad.qml file, see the source code, I know the original layout so simple, directly a grid is done (where columns:3 specifies that each row arranges three elements). However, it is important to note that the "." After and "C" because there is a blank, so when using the grid layout above, you also need to add the corresponding "" Control:

    button {text: "."}    button {text: ""} ...    button {text: "C"; color: "#6da43d"; Operator:true}    Button {text: ""; Color: "#6da43d"; Operator:true}

In the above operator section, where the "±", "?", "√", "÷", "X" Operators are not standard ASCII characters, their hexadecimal values are "c2b1", "E2889" 2, "e2889a", "C3b7", "C397", with " UTF-8 No BOM format "encoding.

Note that the text of the button shown here is one by one related to the Calculator.js script file, that is, if you modify the text of the operator here, it will appear when you click the button to complete the original function (the language is a bit around, This section will be covered in the calculator.js below).

Animationcontroller part

    Animationcontroller {        Id:controller        animation:parallelanimation {            Id:anim            numberanimation {target : Display; Property: "X"; duration:400; From:-16; To:window.width-display.width; Easing.type:Easing.InOutQuad}            numberanimation {Target:pad; property: "X"; duration:400; From:window.width-pad. Width to:0; Easing.type:Easing.InOutQuad}            sequentialanimation {                numberanimation {target:pad; property: ' Scale '; duration:200; From:1; to:0.97; Easing.type:Easing.InOutQuad}                numberanimation {target:pad; property: ' scale '; duration:200; from:0.97; to:1; ea Sing.type:Easing.InOutQuad}}}}    

The Animationcontroller used here is something we didn't meet before, so let's take a look at the official documentation:

Normally animations is driven by a internal timer, but the Animationcontroller allows the given animation to be driven B Y a progress value explicitly.

From the documentation we learned that Animationcontroller is a control that manually controls how animations run in them.

The Animationcontroller has two attributes and three functions, respectively:

Properties

    • Animation:animation
    • Progress:real

Methods

    • Completetobeginning ()
    • Completetoend ()
    • Reload ()

All of the above properties and functions are used in this example, and the following is a gradual expansion.

Animation Properties and Parallelanimation controls

The holds the animation to be controlled by the Animationcontroller.

The meaning of the field is well understood, which refers to the specific animation in the Animationcontroller. The specific use of this is the Parallelanimation control, which we have not encountered before. In fact, parallelanimation very good understanding, the following is the official note:

The sequentialanimation and parallelanimation types allow multiple animations to be run together. Animations defined in a sequentialanimation is run one after the other and while animations defined in a parallelanimation a Re run at the same time.

As can be seen from the description, both Sequentialanimation and parallelanimation encapsulate multiple sub-animation to perform the animation, Only the sub-animation in the sequentialanimation is executed sequentially, while the Parallelanimation animation is executed concurrently. An example of the official has a good demonstration of what situations require multiple animation simultaneous execution:

Rectangle {    id:rect    width:100; height:100    color: "Red"    parallelanimation {        running:true        numberanimation {Target:rect; property: "X", to:50; duration:1000}        numberanimation {target:rect; property: "Y"; to:50; duration:1000}}}    

The above example shows how to make a rectangle move in a diagonal direction.

Let's take a look at the Calqlatr example, what is the animated effect of using the Parallelanimation control?

    Animationcontroller {        Id:controller        animation:parallelanimation {            Id:anim            numberanimation {target : Display; Property: "X"; duration:400; From:-16; To:window.width-display.width; Easing.type:Easing.InOutQuad}            numberanimation {Target:pad; property: "X"; duration:400; From:window.width-pad. Width to:0; Easing.type:Easing.InOutQuad}            sequentialanimation {                numberanimation {target:pad; property: ' Scale '; duration:200; From:1; to:0.97; Easing.type:Easing.InOutQuad}                numberanimation {target:pad; property: ' scale '; duration:200; from:0.97; to:1; ea Sing.type:Easing.InOutQuad}}}}    

which

    • The first numberanimation describes the output part moved from position 16 to Window.width- Display.width; Why is it from-16, because the left side of the divider pattern is hidden at the beginning, and when moved to the window.width-display.width, it hides the divider pattern on the right; see Display section the analysis.
    • The second numberanimation describes the number and operator sections moving from Window.width-pad.width to 0
    • The third one is a sequentialanimation animation combination, the former 200ms,pad part reduced from 100% to 97%, and the latter 200ms,pad from 97% to the 100% size. (If you don't understand, changing the code to 0.97 to 0.5 is a very obvious effect)

In this way, the above three animations are integrated in a Parallelanimation control, and then the animation is done, which results in the final effect (see Running effect).

Progress Property

Let's take a look at the description of the Progress property:

This property holds the animation progress value.
The valid progress value is 0.0 to 1.0, setting values less than 0 would be converted to 0, setting values great than 1 wil L is converted to 1.

Because when you introduce the Parallelanimation control, "Animationcontroller is a control that manually controls how the animation runs," How do you stop the animation at the specific frame? You need to use the Progress property here.

The use of the progress property in this example is slightly more complex, so we can do a special test by using the following code in a button's onclicked function:

    OnClicked:controller.progress = 0.3    (or onClicked:controller.progress = 0.7)

After testing, when the button is clicked, the UI is positioned at 30% (or 70%) according to the animated description in the Animationcontroller control.

The use of progress in this example is done when you drag the button in the lower part of the display, the entire UI follows the mouse's position as it slowly changes.

Completetobeginning () function

Finishes running the controlled animation in a backwards direction.
After calling this method, the animation runs normally from the current progress point in a backwards direction to the beg Inning state.
The animation controller ' s progress value would be automatically updated while the animation is running.

From the instructions above, we learned that the completetobeginning () function is actually executed in reverse from the current position of the animation and changes to the initial knowledge state.

The use of the completetobeginning () function In this example is done when you release the mouse while dragging the button in the lower part of the display from the right to the left, and the entire UI goes back to the primary position rather than the current mouse release ( There are only two UI effects for the UI of the calculator, there is no effect of switching to half.

Completetoend () function

Finishes running the controlled animation in a forwards direction.
After calling this method, the animation runs normally from the current progress point in a forwards direction to the end State.
The animation controller ' s progress value would be automatically updated while the animation is running.

Both the meaning and the use effect are relative to the completetobeginning () function and are not described.

Reload () function

Reloads the animation properties
If the animation properties changed, calling this method to reload the animation definations.

As you can see from the description, when the animation property in the Parallelanimation control changes, you need to call the function to make the UI redraw and create the entire Parallelanimation control state.

Specific to the CALQLATR example, when you use the mouse to change the width and height of the application, you need to re-layout the UI and refresh the state of the Parallelanimation control (such as Completetoend (), you need to move to a farther position).

    OnWidthChanged:controller.reload ()    onHeightChanged:controller.reload ()

Display section

    Display {        id:display        x: -16        width:window.width-pad.width        height:parent.height        mousearea {...}    }

The display control is a custom QML control, specifically implemented in the Display.qml file. When called here, it only sets the x-coordinate, width and height, and the specific action of the Mousearea.

Here's why setting the x-coordinate to 16 is because there is a picture with a 16-edged edge on the left and right sides of the display. Set to-16 so that on the left side, only the right edge pattern is displayed, and when you move to the right, only the sidebar pattern on the left is displayed.

Specific implementation of display controls

Item {    Id:display property    bool Enteringdigits:false    function Displayoperator (operator) {}    function NewLine (operator, operand) {}    function appenddigit (digit) {}    function clear () {}    Item {        Id:theitem        width:parent.width +        height:parent.height        Rectangle {        } image {} image {} image {}        ListView {}    }}

As you can see from the code, the display control has the following elements:

    • A rectangle to change the background of the display part to White to show the process and results
    • Two image shows the left and right edges respectively
    • The third image shows the drag button at the bottom
    • The last ListView is used to display the result of the operation by row
    • Four operators are defined, namely display operators, add new rows, add numbers, and empty processing

These functions, as well as the changes in the ListView, are left in detail in the analysis Calculator.js, which focuses on changes to the QML control.

button action at the bottom of display

        Mousearea {Property            Real startx:0 Property            Real oldp:0 property            bool Rewind:false            anchors {}            Heig Ht:50            onpositionchanged: {}            Onpressed:startx = Maptoitem (window, mouse.x). x            onreleased: {}        }

The Mousearea defines the change in the entire UI as the button is manipulated at the bottom of the display.

First look at the anchors and height sections:

            Anchors {                bottom:parent.bottom                left:parent.left                right:parent.right            }<pre name= "Code" class = "plain" >            height:50

By setting anchors's bottom, left, and right are the corresponding values for the parent, and the height is 50 because the button and the bottom distance is 20 plus the height of the button itself is 30. The end result is that the button's click Range expands to the entire area at the bottom of the display, making it easy for the user to operate.

We continue to analyze the onpositionchanged part of Mousearea:

            Onpositionchanged: {                var reverse = startX > Window.width/2                var mx = maptoitem (window, mouse.x). x                var p = Math.Abs ((MX-STARTX)/(window.width-display.width))                if (P < OLDP)                    rewind = reverse? false:true                Else                    rewind = reverse? true:false                controller.progress = reverse? 1-p: P                OLDP = P            }

Note that the STARTX variable is used here, which is the mouse position that is obtained when the mouse is clicked:

            Onpressed:startx = maptoitem (window, mouse.x). x

One of the Maptoitem functions we learned in theMousearea of QT Demois to map the coordinates in the current space to the position in the window space, simply to get the position of the current mouse based on the entire window.

After getting startx, you can get the operation on the left or right side by comparing it to the horizontal center of the window.

When the mouse moves, again through maptoitem (window, mouse.x). x Gets the current position of the mouse and assigns a value to the MX temp variable. Because the mouse movement is a process, the middle will trigger multiple onpositionchanged callback function, then continuously by comparing the current coordinates and the initial coordinates between the interval, and with the initial mouse position, you can get the mouse last release when the direction of operation. However, throughout the process, the UI animations and mouse synchronization are done by setting the properties of the controller.progress.

The above explanations are complex, and the descriptions are not very clear, and the following scenarios are used to describe them:

    1. button on the left, use the mouse to move to the right: then reverse is false,p value is always greater than OLDP, then rewind and reverse are consistent false, that is, the direction of the mouse movement is ultimately to the right
    2. button on the left side, using coordinates to move to the right of the process to return back: Then reverse is false, the start P value is greater than OLDP, after the return p value starts drizzle OLDP, then rewind and reverse opposite is true, that is, the direction of the mouse movement is ultimately left
    3. button on the right, use the mouse to move to the left: then the reverse is true,p value is always greater than OLDP, then rewind and reverse are consistent true, that is, the direction of the mouse movement is ultimately left

    4. button on the right side, use the coordinates to move to the left to return back: Then reverse is true, the start P value is greater than OLDP, after the return p value starts drizzle OLDP, then rewind and reverse is false, that is, the direction of the mouse movement is ultimately the right

But there are two scenarios that are not considered, that is:

    • button on the left, use your mouse to move to the left
    • button on the right, use your mouse to move right

In fact, you can add conditions to limit, just note the absolute value of the p used here, in handling the above four scenarios, convenient but not cover all the scenes. How to optimize the code here makes it possible to cover both of the above scenarios, which are no longer detailed here. If the reader is not clear here, then you can communicate.


According to the above scenario analysis, when the mouse's final movement direction is determined, when the mouse button is released, the UI animation will need to switch to the beginning or end of the state, rather than stay in the middle of a state.

            Onreleased: {                if (rewind)//The mouse moves toward the left                    controller.completetobeginning ()                else//the direction of the mouse movement is ultimately the right                    Controller.completetoend ()            }
Summarize

New knowledge learned in this section:

    1. OnPropertyChanged Series functions
    2. Learning and using of Animationcontroller controls

At the very beginning of contact with QML, at first glance Calqlatr QML code is completely confused, after several previous analysis on the basis, now in to learn CALQLATR code is not so complex and difficult to understand.

This blog post is long, and it took me almost a week to complete my spare time. In contrast to the previous sample code, although all of the various QML controls are used, the processing part of this example, especially Mousearea, adds a lot of business logic, and the understanding is not there directly.

Do not know the specific efficiency, but from the writing of the code, the sense of Qt qml for the UI is still pretty strong.

QT Demo Calqlatr (2) calqlatr.qml

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.