| 1 | /**************************************************************************** | 
|---|
| 2 | ** | 
|---|
| 3 | ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). | 
|---|
| 4 | ** All rights reserved. | 
|---|
| 5 | ** Contact: Nokia Corporation (qt-info@nokia.com) | 
|---|
| 6 | ** | 
|---|
| 7 | ** This file is part of the documentation of the Qt Toolkit. | 
|---|
| 8 | ** | 
|---|
| 9 | ** $QT_BEGIN_LICENSE:FDL$ | 
|---|
| 10 | ** Commercial Usage | 
|---|
| 11 | ** Licensees holding valid Qt Commercial licenses may use this file in | 
|---|
| 12 | ** accordance with the Qt Commercial License Agreement provided with the | 
|---|
| 13 | ** Software or, alternatively, in accordance with the terms contained in a | 
|---|
| 14 | ** written agreement between you and Nokia. | 
|---|
| 15 | ** | 
|---|
| 16 | ** GNU Free Documentation License | 
|---|
| 17 | ** Alternatively, this file may be used under the terms of the GNU Free | 
|---|
| 18 | ** Documentation License version 1.3 as published by the Free Software | 
|---|
| 19 | ** Foundation and appearing in the file included in the packaging of this | 
|---|
| 20 | ** file. | 
|---|
| 21 | ** | 
|---|
| 22 | ** If you have questions regarding the use of this file, please contact | 
|---|
| 23 | ** Nokia at qt-info@nokia.com. | 
|---|
| 24 | ** $QT_END_LICENSE$ | 
|---|
| 25 | ** | 
|---|
| 26 | ****************************************************************************/ | 
|---|
| 27 |  | 
|---|
| 28 |  | 
|---|
| 29 |  | 
|---|
| 30 | /*! | 
|---|
| 31 | \page qml-intro.html | 
|---|
| 32 | \title Intro to Qt Quick | 
|---|
| 33 |  | 
|---|
| 34 | \section1 Overview | 
|---|
| 35 |  | 
|---|
| 36 | QML is a high level, scripted language. Its commands, more correctly \e elements, | 
|---|
| 37 | leverage the power and efficiency of the Qt libraries to make easy to use | 
|---|
| 38 | commands that perform intuitive functions. Draw a rectangle, display an image at | 
|---|
| 39 | a position and so on. Behind these elements are complex C++ libraries that | 
|---|
| 40 | efficiently perform the action. As with any graphical application, always | 
|---|
| 41 | consider that this ability to easily build graphically rich applications means | 
|---|
| 42 | that some care may be needed to prevent performance problems. | 
|---|
| 43 |  | 
|---|
| 44 | The language also allows more flexibility of these commands by using | 
|---|
| 45 | Javascript rather than C++ to add new layers of logic to your application. | 
|---|
| 46 | Javascript is easier to learn than C++ and can be embedded into the QML | 
|---|
| 47 | files or imported from a separate file. | 
|---|
| 48 |  | 
|---|
| 49 | \bold{In QML the types of various 'objects' are referred to as \l {QML | 
|---|
| 50 | Elements}{elements}}. | 
|---|
| 51 |  | 
|---|
| 52 | An element usually has various \e properties that help define the element. For | 
|---|
| 53 | example, if we created an element called Circle then the radius of the circle | 
|---|
| 54 | would be a property. | 
|---|
| 55 |  | 
|---|
| 56 |  | 
|---|
| 57 | \section1 A First Look | 
|---|
| 58 |  | 
|---|
| 59 | The basic syntax of an \l{QML Elements}{element} is | 
|---|
| 60 |  | 
|---|
| 61 | \qml | 
|---|
| 62 | SomeElement { | 
|---|
| 63 | id: myObject | 
|---|
| 64 | ... some other things here ... | 
|---|
| 65 | } | 
|---|
| 66 | \endqml | 
|---|
| 67 |  | 
|---|
| 68 | Here we are defining a new object. We specify its 'type' first as SomeElement. | 
|---|
| 69 | Then within matching braces { ... } we specify the various parts of our | 
|---|
| 70 | element. | 
|---|
| 71 |  | 
|---|
| 72 | The \c id is a unique identifier for the element, it must start with a lower | 
|---|
| 73 | case letter and only contain letters, numbers and underscores. It is this | 
|---|
| 74 | particular object's name. If this SomeElement \l {QML Elements}{element} was | 
|---|
| 75 | a Rectangle instead and it was one of many then the \e optional unique id | 
|---|
| 76 | would allow us to manipulate each element individually. | 
|---|
| 77 |  | 
|---|
| 78 | Each visual element is ultimately based on, or inherits from, an element | 
|---|
| 79 | called \l Item. \l Item has certain properties and actions that may be | 
|---|
| 80 | useful. The properties have default values so you need only specify the | 
|---|
| 81 | ones you will need. | 
|---|
| 82 |  | 
|---|
| 83 | Take a simple element such as a \l Rectangle. It has an \c id, we will call | 
|---|
| 84 | it \e myRectangle, it has a \c width and a \c height. Imagine that we | 
|---|
| 85 | want a rectangle that is 500 pixels by 400 pixels in the x and y directions | 
|---|
| 86 | (horizontal by vertical). | 
|---|
| 87 |  | 
|---|
| 88 | We can implement this \l Rectangle with these properties this way | 
|---|
| 89 |  | 
|---|
| 90 | \snippet doc/src/snippets/declarative/qml-intro/rectangle.qml document | 
|---|
| 91 |  | 
|---|
| 92 | This is a valid QML script. To run it, copy it and save it to a file, say | 
|---|
| 93 | myexample.qml, and on the command line run the following command: | 
|---|
| 94 |  | 
|---|
| 95 | \code | 
|---|
| 96 | qmlviewer myexample.qml | 
|---|
| 97 | \endcode | 
|---|
| 98 |  | 
|---|
| 99 | On Mac OS X, open the "QMLViewer" application instead and open the | 
|---|
| 100 | \c myexample.qml file, or run it from the command line: | 
|---|
| 101 |  | 
|---|
| 102 | \code | 
|---|
| 103 | QMLViewer.app/Contents/MacOS/QMLViewer myexample.qml | 
|---|
| 104 | \endcode | 
|---|
| 105 |  | 
|---|
| 106 | It will create a very boring rectangle in its own window. | 
|---|
| 107 |  | 
|---|
| 108 |  | 
|---|
| 109 | \section1 Hello World! | 
|---|
| 110 |  | 
|---|
| 111 | We can now add some color and text to make a Hello World QML program. | 
|---|
| 112 |  | 
|---|
| 113 | \l Rectangle has the property \l{Rectangle::color}{color} to produce a | 
|---|
| 114 | background color. | 
|---|
| 115 |  | 
|---|
| 116 | Text is handled by a different element called \l Text. We need to create a | 
|---|
| 117 | \l Text object inside the \l Rectangle and set its \l{Text::}{text} | 
|---|
| 118 | property to "Hello World!". So to set the text to "Hello world" and the | 
|---|
| 119 | background colour to light gray, | 
|---|
| 120 |  | 
|---|
| 121 | \snippet doc/src/snippets/declarative/qml-intro/hello-world1.qml document | 
|---|
| 122 |  | 
|---|
| 123 |  | 
|---|
| 124 | \section1 Hello World Again | 
|---|
| 125 |  | 
|---|
| 126 | From now on we will not always show the import statement for Qt but it | 
|---|
| 127 | should still be there when you create your QML scripts. | 
|---|
| 128 |  | 
|---|
| 129 | To make our Hello World example a little nicer set the position of the text | 
|---|
| 130 | to be at pixel position x = 100, y = 100 within the displayed window. This | 
|---|
| 131 | position belongs to the \l Text element so we set the position inside its | 
|---|
| 132 | definition. Note that we separate different QML statements on the same line | 
|---|
| 133 | with a semi-colon, or we could have simply put each statement on a new line | 
|---|
| 134 |  | 
|---|
| 135 | \snippet doc/src/snippets/declarative/qml-intro/hello-world2.qml updated text | 
|---|
| 136 |  | 
|---|
| 137 | Not only did we reposition the text, but the text was altered by adding | 
|---|
| 138 | HTML tags to change the font size. The text color was also changed from the | 
|---|
| 139 | default black to dark green by using a standard string for the color's SVG | 
|---|
| 140 | name. | 
|---|
| 141 |  | 
|---|
| 142 | We could also have used a hexadecimal string for the RGB (red-green-blue, as | 
|---|
| 143 | #rrggbb) values of the color similar to the method used in HTML. For | 
|---|
| 144 | example, mostly blue with a green tint, | 
|---|
| 145 |  | 
|---|
| 146 | \snippet doc/src/snippets/declarative/qml-intro/hello-world3.qml updated text | 
|---|
| 147 |  | 
|---|
| 148 | All of these changes occurred within the \l Text object which is the scope | 
|---|
| 149 | of these property changes. | 
|---|
| 150 |  | 
|---|
| 151 | Other objects may use the information but it belongs to the element where | 
|---|
| 152 | the property has been defined. | 
|---|
| 153 |  | 
|---|
| 154 |  | 
|---|
| 155 | \section1 Images | 
|---|
| 156 |  | 
|---|
| 157 | To add an image to our little application we use the \l Image element. An | 
|---|
| 158 | \l Image uses a path to an image file, and has properties to control | 
|---|
| 159 | the aspect ratio, the image size, to tile the area amongst others. The | 
|---|
| 160 | source of the image, the path to the file, is a URL. Therefore the file can | 
|---|
| 161 | be local: \e {mydir/myimage1.png}. Or it can be remote: | 
|---|
| 162 | \e {"http://www.example.com/images/myimage1.png"}. | 
|---|
| 163 |  | 
|---|
| 164 | \snippet doc/src/snippets/declarative/qml-intro/hello-world4.qml added an image | 
|---|
| 165 |  | 
|---|
| 166 | This displays the image, as we would expect, at the top left of the window. | 
|---|
| 167 | The position of the default x = 0, y = 0 coordinate. The example here uses | 
|---|
| 168 | a PNG file, but it could have been one of various supported formats, | 
|---|
| 169 | including JPG and GIF. | 
|---|
| 170 |  | 
|---|
| 171 | Let us reposition the image and enlarge it. Place it at the same 'x' offset | 
|---|
| 172 | as the "Hello world again" text, but put it another 50 pixels below the | 
|---|
| 173 | text, also make it 150 by 150 pixels in size, | 
|---|
| 174 |  | 
|---|
| 175 | \snippet doc/src/snippets/declarative/qml-intro/hello-world5.qml positioning the image | 
|---|
| 176 |  | 
|---|
| 177 | Adding the Hello World example, with the text and the image example we can | 
|---|
| 178 | write a simple piece of QML that starts to look a bit better. | 
|---|
| 179 |  | 
|---|
| 180 | \snippet doc/src/snippets/declarative/qml-intro/hello-world5.qml document | 
|---|
| 181 |  | 
|---|
| 182 | The result is still quite simple | 
|---|
| 183 |  | 
|---|
| 184 | \image qml-intro-helloa.png | 
|---|
| 185 |  | 
|---|
| 186 |  | 
|---|
| 187 | \section1 Anchors: Aligning Elements | 
|---|
| 188 |  | 
|---|
| 189 | Using absolute positioning, such as saying x = 100 and y = 150, works well | 
|---|
| 190 | until the user or developer stretches or increases the size of the window. | 
|---|
| 191 | Then the positions need to be recalculated. What would be nice would be a | 
|---|
| 192 | relative means of positioning of objects in a window or rectangle. For | 
|---|
| 193 | example, we want to place an image at the bottom of a rectangle, we would | 
|---|
| 194 | like to specify the image's location as the 'bottom of the window', not a | 
|---|
| 195 | specific coordinate. We can do this with the anchors property, which | 
|---|
| 196 | objects inherit from Item. | 
|---|
| 197 |  | 
|---|
| 198 | The anchors property is really a property group. It is a collection of | 
|---|
| 199 | related properties. It has properties within it which can be used by means | 
|---|
| 200 | of the dot notation. | 
|---|
| 201 |  | 
|---|
| 202 | The dot notation uses object \c{id}s and property names to use a particular | 
|---|
| 203 | object or property. Say I have a rectangle r1, which contains a rectangle | 
|---|
| 204 | r2, which contains an Item item1, which has an 'x' property I want to | 
|---|
| 205 | change. I just use the dot notation to identify it: r1.r2.item1.x | 
|---|
| 206 |  | 
|---|
| 207 | If we want to position an image at the bottom of the rectangle it is | 
|---|
| 208 | inside. I have to specify that the bottom of the image is also at the | 
|---|
| 209 | bottom of the rectangle | 
|---|
| 210 |  | 
|---|
| 211 | \snippet doc/src/snippets/declarative/qml-intro/anchors1.qml document | 
|---|
| 212 |  | 
|---|
| 213 | This places the logo at the bottom left of the window. | 
|---|
| 214 |  | 
|---|
| 215 | \image qml-intro-anchors1.png  "A simple anchor" | 
|---|
| 216 |  | 
|---|
| 217 | We would like it centered and not touching the bottom of the window, for | 
|---|
| 218 | aesthetic reasons. For the centering we use the horizontalCenter property, | 
|---|
| 219 | and to prevent the touching of the image to the bottom of the rectangle, | 
|---|
| 220 | the bottomMargin property is used. So the new actions for the script are | 
|---|
| 221 |  | 
|---|
| 222 | \list | 
|---|
| 223 | \o set the bottom of the image (anchors.bottom) to be the bottom of the window | 
|---|
| 224 | \o move the image to be in the horizontal center of the window | 
|---|
| 225 | \o set a margin of 10 pixels so that the image does not touch the bottom window border | 
|---|
| 226 | \endlist | 
|---|
| 227 |  | 
|---|
| 228 | Encoded into QML the script becomes | 
|---|
| 229 |  | 
|---|
| 230 | \snippet doc/src/snippets/declarative/qml-intro/anchors2.qml document | 
|---|
| 231 |  | 
|---|
| 232 | Run this and resize the window. You will see that now the position of the | 
|---|
| 233 | image adjusts during the resize. | 
|---|
| 234 |  | 
|---|
| 235 | \image qml-intro-anchors2.png  "Image Centered at the Bottom" | 
|---|
| 236 |  | 
|---|
| 237 | You can also add another object say a block of descriptive text and place | 
|---|
| 238 | it above or below the image or to the side. This code places some text just | 
|---|
| 239 | above the image | 
|---|
| 240 |  | 
|---|
| 241 | \snippet doc/src/snippets/declarative/qml-intro/anchors3.qml adding some text | 
|---|
| 242 |  | 
|---|
| 243 | \image qml-intro-anchors3.png | 
|---|
| 244 |  | 
|---|
| 245 | \note \e anchors is a property group, to be used within the object. When | 
|---|
| 246 | referencing these properties from another object we use the property | 
|---|
| 247 | directly, instead of saying: | 
|---|
| 248 |  | 
|---|
| 249 | \qml | 
|---|
| 250 | myRectangle.anchors.top  // Wrong | 
|---|
| 251 | \endqml | 
|---|
| 252 |  | 
|---|
| 253 | we use | 
|---|
| 254 |  | 
|---|
| 255 | \qml | 
|---|
| 256 | myRectangle.top         // Correct | 
|---|
| 257 | \endqml | 
|---|
| 258 |  | 
|---|
| 259 |  | 
|---|
| 260 | \section1 Transformations | 
|---|
| 261 |  | 
|---|
| 262 | We can transform a graphical object to get additional effects. Rotate a | 
|---|
| 263 | piece of text by 180 degrees to display upside-down text. Rotate an image | 
|---|
| 264 | by 90 degrees to lay it on its side. These transformations require | 
|---|
| 265 | additional information. | 
|---|
| 266 |  | 
|---|
| 267 | For rotation, the additional information includes: the origin relative to | 
|---|
| 268 | the object being rotated, the axis of rotation, and the angle in degrees to | 
|---|
| 269 | rotate the image through in a clockwise direction. The axis does not have | 
|---|
| 270 | to be the z-axis, the line between your eyes and the image, it could be | 
|---|
| 271 | along the vertical y-axis or the horizontal x-axis. We have three | 
|---|
| 272 | dimensions to play with. For simplicity in this example we will rotate | 
|---|
| 273 | about the z-axis by 90 degrees in a negative direction, anti-clockwise. | 
|---|
| 274 |  | 
|---|
| 275 | Rotation of text was also suggested. It could also be useful to scale the | 
|---|
| 276 | text. We can do both. The \l {Item::transform}{transform} property is a | 
|---|
| 277 | \e list of \l Transform elements, so using the list syntax | 
|---|
| 278 |  | 
|---|
| 279 | \qml | 
|---|
| 280 | myList: [ listElement1, listElement2, ... } ] | 
|---|
| 281 | \endqml | 
|---|
| 282 |  | 
|---|
| 283 | we can produce a list of transformations. | 
|---|
| 284 |  | 
|---|
| 285 | The text will be rotated by 45 degrees anti-clockwise and scaled | 
|---|
| 286 | vertically by a factor of 1.5 and by 1.2 horizontally. | 
|---|
| 287 |  | 
|---|
| 288 | Using the example above as the basis for this we have, | 
|---|
| 289 |  | 
|---|
| 290 | \snippet doc/src/snippets/declarative/qml-intro/transformations1.qml document | 
|---|
| 291 |  | 
|---|
| 292 | The code block in \c image1 starting with \c transform specifies that the | 
|---|
| 293 | \l {Item::transform}{transform} property will be a Rotation through -90 | 
|---|
| 294 | degrees, which is anti-clockwise, about the z-axis running through the | 
|---|
| 295 | center of the image at (75,75), since the image is 150 x 150 pixels. | 
|---|
| 296 |  | 
|---|
| 297 | The other transformation available is \l Translate. This produces a change | 
|---|
| 298 | in position of the item. | 
|---|
| 299 |  | 
|---|
| 300 | \note In a list of transformations the order of the transformations is | 
|---|
| 301 | important. In the above example try swapping around the Scale transform with | 
|---|
| 302 | the Rotation transform, remember to remove or add the comma. The results are | 
|---|
| 303 | acceptable for our little test but not the same. | 
|---|
| 304 |  | 
|---|
| 305 |  | 
|---|
| 306 | \section1 Animations | 
|---|
| 307 |  | 
|---|
| 308 | Animation in QML is done by animating properties of objects. Properties | 
|---|
| 309 | that are numbers, colors, Rectangles, points and directions. In QML these | 
|---|
| 310 | are \l {QML Basic Types} named as real, int, color, rect, point, size, and | 
|---|
| 311 | vector3d. There are a number of different ways to do animation. Here we | 
|---|
| 312 | will look at a few of them. | 
|---|
| 313 |  | 
|---|
| 314 | \section2 Number Animation | 
|---|
| 315 |  | 
|---|
| 316 | Previously we have used a rotation transformation to change the orientation | 
|---|
| 317 | of an image. We could easily animate this rotation so that instead of a | 
|---|
| 318 | straight rotation counter-clockwise of 90 degrees we could rotate the image | 
|---|
| 319 | through a full 360 degrees in an animation. The axis of rotation wont | 
|---|
| 320 | change, the position of the center of the image will not change, only the | 
|---|
| 321 | angle will change. Therefore, a NumberAnimation of a rotation's angle should | 
|---|
| 322 | be enough for the task. If we wish for a simple rotation about the center | 
|---|
| 323 | of the image then we can use the \c rotation property that is inherited | 
|---|
| 324 | from \l Item. The rotation property is a real number that specifies the | 
|---|
| 325 | angle in a clockwise direction for the rotation of the object. Here is the | 
|---|
| 326 | code for our animated rotating image. | 
|---|
| 327 |  | 
|---|
| 328 | \snippet doc/src/snippets/declarative/qml-intro/number-animation1.qml document | 
|---|
| 329 |  | 
|---|
| 330 | The \c {transformOrigin: Item.Center} is redundant since this is the default | 
|---|
| 331 | axis of rotation anyway. But if you change \c Center to \c BottomRight you | 
|---|
| 332 | will see an interesting variation. | 
|---|
| 333 |  | 
|---|
| 334 | Also if instead the \l Rotation transformation had been used then we would have | 
|---|
| 335 | more control over the various parameters. We could vary the axis, to be not | 
|---|
| 336 | just a different offset from the z-axis but along the y-axis, x-axis or | 
|---|
| 337 | combination. For example, if the task had been to animate the rotation | 
|---|
| 338 | about the y-axis passing through the center of the image then the following | 
|---|
| 339 | code would do it. | 
|---|
| 340 |  | 
|---|
| 341 | \snippet doc/src/snippets/declarative/qml-intro/number-animation2.qml document | 
|---|
| 342 |  | 
|---|
| 343 | Here there is a rectangle 600 by 400 pixels. Placed within that rectangle | 
|---|
| 344 | is an image 100 by 100 pixels. It is rotated about the center of the image | 
|---|
| 345 | about the y-axis so that it looks as if it is rotating about an invisible | 
|---|
| 346 | vertical string holding it up. The time it takes to complete the rotation is 3 | 
|---|
| 347 | seconds (3,000 milliseconds). The NumberAnimation is applied to the angle | 
|---|
| 348 | taking it from 0 (no change) to 360 degrees, back where it started. | 
|---|
| 349 | Strictly speaking it isn't necessary to go from 0 to 360 since the same | 
|---|
| 350 | location is duplicated, but it makes it easier to read in this example and | 
|---|
| 351 | it has no visible effect on the animation. The number of loops that the | 
|---|
| 352 | animation will execute is set to \c {Animation.Infinite} which means that the | 
|---|
| 353 | animation is in an endless loop. | 
|---|
| 354 |  | 
|---|
| 355 | To see an interesting variation. Change the axis to \c {axis { x:1; y:1; z:1 | 
|---|
| 356 | }}. This is a line coming from the center of the image downwards to the | 
|---|
| 357 | right and out of the screen. Although the change is simple the rotation | 
|---|
| 358 | seems complex. | 
|---|
| 359 |  | 
|---|
| 360 | \section2 Sequential Animation | 
|---|
| 361 |  | 
|---|
| 362 | For a more complex animation we will need two images. The first image will | 
|---|
| 363 | be placed at the center of a window (Rectangle) and the second image will | 
|---|
| 364 | be at the upper left of the window. The animation will move the second | 
|---|
| 365 | image from the top left of the window to the bottom right. In doing so we | 
|---|
| 366 | will be animating the position and the size of the image. | 
|---|
| 367 |  | 
|---|
| 368 | First create two images | 
|---|
| 369 |  | 
|---|
| 370 | \snippet doc/src/snippets/declarative/qml-intro/sequential-animation1.qml document | 
|---|
| 371 |  | 
|---|
| 372 | We will add to 'image1' a SequentialAnimation from x = 20 to the target of | 
|---|
| 373 | x = 450. The 'from' values will be used because we will be repeating the | 
|---|
| 374 | animation, so the object needs to know where the original position is, both | 
|---|
| 375 | x and y. The SequentialAnimation of x will set it to repeat by indicating | 
|---|
| 376 | that the number of animation loops is infinite, meaning that the 'loop' | 
|---|
| 377 | counter will be set to a value Animation.Infinite that indicates an endless | 
|---|
| 378 | cycle. Also there will be a NumberAnimation to vary the numeric property | 
|---|
| 379 | between the x values and over a given duration. After the NumberAnimation | 
|---|
| 380 | there will be a PauseAnimation that will pause the animation for 500 | 
|---|
| 381 | milliseconds (half a second) simply for the visual effect. | 
|---|
| 382 |  | 
|---|
| 383 | \snippet doc/src/snippets/declarative/qml-intro/sequential-animation2.qml adding a sequential animation | 
|---|
| 384 |  | 
|---|
| 385 | A similar block of code is written for the animation of the 'y' value of | 
|---|
| 386 | the position. | 
|---|
| 387 |  | 
|---|
| 388 | We will also animate the scale of the object, so as it goes from top left | 
|---|
| 389 | to bottom right of the window it will become smaller until about midway, | 
|---|
| 390 | and then become larger. To complete the animation we will set the 'z' | 
|---|
| 391 | values of the images. 'z' is the stacking order, the z-axis effectively | 
|---|
| 392 | points out from the screen to your eyes with the default value of 'z' being | 
|---|
| 393 | 0. So if we set the Rectangle to have z with value zero, just to be sure, | 
|---|
| 394 | and image1 to 1 and image2 to 2 then image2 will be in the foreground and | 
|---|
| 395 | image1 in the background. When image1 passes image2 it will pass behind it. | 
|---|
| 396 | The completed code looks like | 
|---|
| 397 |  | 
|---|
| 398 | \snippet doc/src/snippets/declarative/qml-intro/sequential-animation3.qml document | 
|---|
| 399 |  | 
|---|
| 400 | The \c {easing.type} has many options, expressed as a string. It specifies the | 
|---|
| 401 | kind of equation that describes the acceleration of the property value, not | 
|---|
| 402 | necessarily position, over time. | 
|---|
| 403 |  | 
|---|
| 404 | For example, \e InOutQuad means that at the start and the end of the animation the | 
|---|
| 405 | 'velocity' is low but the acceleration or deceleration is high. Much like a car | 
|---|
| 406 | accelerating from stop, and decelerating to stop at the end of a journey, | 
|---|
| 407 | with the maximum speed being in the middle. Examine the \l {PropertyAnimation::easing.type} | 
|---|
| 408 | {easing} documentation and the various graphs that show the effect. The horizontal | 
|---|
| 409 | axis, 'progress', can be thought of as time. The vertical axis is the value | 
|---|
| 410 | of the particular property. | 
|---|
| 411 |  | 
|---|
| 412 | In discussing animation we need to describe three objects: State, MouseArea | 
|---|
| 413 | and Signals. Although independent of the animation elements, animation | 
|---|
| 414 | delivers some of the best examples that illustrate these new elements. | 
|---|
| 415 |  | 
|---|
| 416 |  | 
|---|
| 417 |  | 
|---|
| 418 | \section2 Animation Summary | 
|---|
| 419 |  | 
|---|
| 420 | \table | 
|---|
| 421 | \header | 
|---|
| 422 | \o Name | 
|---|
| 423 | \o Description | 
|---|
| 424 | \row | 
|---|
| 425 | \o PropertyAnimation | 
|---|
| 426 | \o a property value on a target object is varied to a specified value over a given time. | 
|---|
| 427 |  | 
|---|
| 428 | \row | 
|---|
| 429 | \o NumberAnimation | 
|---|
| 430 | \o animate a numeric property from one value to another over a given time. | 
|---|
| 431 |  | 
|---|
| 432 | \row | 
|---|
| 433 | \o PauseAnimation | 
|---|
| 434 | \o results in the task waiting for the specified duration, in milliseconds. | 
|---|
| 435 |  | 
|---|
| 436 | \row | 
|---|
| 437 | \o SequentialAnimation | 
|---|
| 438 | \o allows us to list in order the animation events we want to occur, first A then B then C and so on. | 
|---|
| 439 |  | 
|---|
| 440 | \row | 
|---|
| 441 | \o ParallelAnimation | 
|---|
| 442 | \o enables us to run different animations at the same time instead of sequentially. | 
|---|
| 443 |  | 
|---|
| 444 | \endtable | 
|---|
| 445 |  | 
|---|
| 446 |  | 
|---|
| 447 | \section1 Using States | 
|---|
| 448 |  | 
|---|
| 449 | A state is a defined set of values in the configuration of an object and | 
|---|
| 450 | often depends on the previous state. For example, a glass could be in a | 
|---|
| 451 | state we call 'HalfFull' if it is being filled with a liquid and has | 
|---|
| 452 | reached half of its total capacity. We could also have a state called | 
|---|
| 453 | HalfEmpty which is the state that occurs when the amount of liquid drops to | 
|---|
| 454 | half of the glass's capacity. Both states represent the same amount of | 
|---|
| 455 | liquid, but we consider them different. Likewise, states in a program | 
|---|
| 456 | represent not just values but may include how the current values were | 
|---|
| 457 | reached. | 
|---|
| 458 |  | 
|---|
| 459 | When a state changes a \e transition occurs. This is an opportunity to make | 
|---|
| 460 | changes or take actions that depend on the movement to the new state. For | 
|---|
| 461 | example, if we had a scene in the country where the state variable has two | 
|---|
| 462 | states "daylight" and "night". Then when the state changes to "night" at | 
|---|
| 463 | this transition the sky would be made dark, stars would be shown, the | 
|---|
| 464 | countryside would be darkened. And when the state changes to "daylight" the | 
|---|
| 465 | opposite changes would be made: the sky is now blue, the scenery is green, | 
|---|
| 466 | there is a sun in the sky. | 
|---|
| 467 |  | 
|---|
| 468 | Here is a simple QML program that shows the change of state in the above | 
|---|
| 469 | example. We have two rectangles, the top one is the 'sky' and the bottom | 
|---|
| 470 | one is the 'ground'. We will animate the change from daylight to night. | 
|---|
| 471 | There will be two states, but we only need to define one since 'daylight' | 
|---|
| 472 | will be the default state. We will just go to 'night' by clicking and | 
|---|
| 473 | holding the left mouse button down, releasing the mouse button will reverse | 
|---|
| 474 | the process | 
|---|
| 475 |  | 
|---|
| 476 | \snippet doc/src/snippets/declarative/qml-intro/states1.qml document | 
|---|
| 477 |  | 
|---|
| 478 | Several new things appear in this sample. Firstly, we use a \l MouseArea | 
|---|
| 479 | element to detect mouse clicks in the \e mainRectangle. Secondly, we use | 
|---|
| 480 | the list notation [ thing1 , thing2, ... ] to build a list of states and a | 
|---|
| 481 | list of transitions. | 
|---|
| 482 |  | 
|---|
| 483 | \l MouseArea defines a region that will respond to mouse clicks. In this case | 
|---|
| 484 | we are only concerned with when the mouse is pressed or not pressed, not | 
|---|
| 485 | the particular button or other details. The area of the MouseArea is the | 
|---|
| 486 | entire main window, mainRectangle, so that clicking anywhere in this region | 
|---|
| 487 | will start the animation. Since we are using the 'pressed' mouse state, | 
|---|
| 488 | then the animation will move from 'daylight' to 'night' only while the mouse | 
|---|
| 489 | button remains pressed. | 
|---|
| 490 |  | 
|---|
| 491 | When the button is released the 'daylight' state is entered and the | 
|---|
| 492 | transition from 'night' to 'daylight' is triggered causing the animation to | 
|---|
| 493 | run. The transition specifies the duration in milliseconds of the | 
|---|
| 494 | ColorAnimation, while the state specifies the color of the new state. | 
|---|
| 495 |  | 
|---|
| 496 | The PropertyChanges command is the way that we nominate which properties | 
|---|
| 497 | will change in a change of state, and what new value the property will | 
|---|
| 498 | take. Since, for example, we want the 'sky' region to turn to dark blue and | 
|---|
| 499 | the 'ground' region to turn to black for the 'night' state, then the | 
|---|
| 500 | rectangles for those regions are the 'target' and the property in the target | 
|---|
| 501 | is 'color'. | 
|---|
| 502 |  | 
|---|
| 503 |  | 
|---|
| 504 | \section1 Signals | 
|---|
| 505 |  | 
|---|
| 506 | Signals are simply events that can be hooked up to actions we want performed. | 
|---|
| 507 | In QML they are usually preceded by the word 'on', for example in the animation | 
|---|
| 508 | using a MouseArea the signal was \l {MouseArea::onPressed}{onPressed}. If | 
|---|
| 509 | you look at the C++ documentation you will see a lot of talk about | 
|---|
| 510 | \l {Signals & Slots}{Signals and Slots}. Signals are connected to Slots. The | 
|---|
| 511 | signal represents an event and the Slot is the function that does something | 
|---|
| 512 | based on that event. You can also have Signals connected to other Signals, so | 
|---|
| 513 | that one Signal (event) triggers another Signal (event), and so forth. It is | 
|---|
| 514 | nice to know this is what happens beneath the QML layer but not essential for | 
|---|
| 515 | using QML. | 
|---|
| 516 |  | 
|---|
| 517 | Most elements do not have Signals associated with them. However, a few like | 
|---|
| 518 | the \l Audio element have many signals. Some of the \l Audio signals are | 
|---|
| 519 | used to represent events such as when the audio is stopped, play is pressed, | 
|---|
| 520 | paused, and reaching the end of the media. They allow the developer to connect, | 
|---|
| 521 | for example, the press of a user interface button (perhaps a MouseArea) to | 
|---|
| 522 | some QML that will handle this event. | 
|---|
| 523 |  | 
|---|
| 524 |  | 
|---|
| 525 | \section1 Analyzing An Example: Dial Control | 
|---|
| 526 |  | 
|---|
| 527 | In the Qt \e {examples/declarative/ui-components} folder you will find a folder | 
|---|
| 528 | \e {dialcontrol} which contains the \e dialcontrol example. | 
|---|
| 529 |  | 
|---|
| 530 | \image qml-dial.png  "QML Dial example with Slider" | 
|---|
| 531 |  | 
|---|
| 532 | In essence this small application has a sliding bar that you can slide using | 
|---|
| 533 | a mouse, and a graphical dial that responds to the position of the slider. | 
|---|
| 534 |  | 
|---|
| 535 | The code for the example is in two parts: Dial.qml and dialcontrol.qml. | 
|---|
| 536 |  | 
|---|
| 537 | \e {Dial.qml} can be found in the \e content sub-directory. It defines a \c Dial | 
|---|
| 538 | component similar to an odometer. Eventually, the example will hook up a slider | 
|---|
| 539 | component so that moving the slider will change the position of a needle on the | 
|---|
| 540 | dial. | 
|---|
| 541 |  | 
|---|
| 542 | The code for the \c Dial, identified by the name of the file, contains four images | 
|---|
| 543 | in overlapping order: the background (numbers and divisions), the shadow of the | 
|---|
| 544 | needle, the needle itself, and finally the 'glass' overlay (containing | 
|---|
| 545 | transparent layers). | 
|---|
| 546 |  | 
|---|
| 547 | The \c needle_shadow.png image has a \l Rotation assigned to the \e transform | 
|---|
| 548 | attribute of the \l Image. The rotation is set to match the angle of the needle | 
|---|
| 549 | image angle value \e {needleRotation.angle}. Both the needle and the | 
|---|
| 550 | needle_shadow have the same default \e x and \e y values but the rotation origin | 
|---|
| 551 | for the needle is slightly different so that a shadow will be evident as the | 
|---|
| 552 | needle moves. | 
|---|
| 553 |  | 
|---|
| 554 | \snippet examples/declarative/ui-components/dialcontrol/content/Dial.qml  needle_shadow | 
|---|
| 555 |  | 
|---|
| 556 | And the needle | 
|---|
| 557 |  | 
|---|
| 558 | \snippet examples/declarative/ui-components/dialcontrol/content/Dial.qml  needle | 
|---|
| 559 |  | 
|---|
| 560 | The final image is the overlay which simply has a position defined. | 
|---|
| 561 |  | 
|---|
| 562 | \snippet examples/declarative/ui-components/dialcontrol/content/Dial.qml  overlay | 
|---|
| 563 |  | 
|---|
| 564 | \e {dialcontrol.qml} in the \e {examples/declarative/ui-components/dialcontrol} directory is the | 
|---|
| 565 | main file of the example. It defines the visual environment that the Dial | 
|---|
| 566 | will fit into. Because the \e Dial component and the images live in the \e | 
|---|
| 567 | content sub-directory we will have to import this into \e dialcontrol.qml. So the | 
|---|
| 568 | start of the file looks like | 
|---|
| 569 |  | 
|---|
| 570 | \snippet examples/declarative/ui-components/dialcontrol/dialcontrol.qml  imports | 
|---|
| 571 |  | 
|---|
| 572 | The visual space is bound by a 300 by 300 pixel \l Rectangle which is given | 
|---|
| 573 | a gray color. Inside this rectangle is our component \e Dial and a \l Rectangle. | 
|---|
| 574 | Inside the rectangle called 'container' is another rectangle with the | 
|---|
| 575 | interesting name 'slider'. | 
|---|
| 576 |  | 
|---|
| 577 | \snippet examples/declarative/ui-components/dialcontrol/dialcontrol.qml  0 | 
|---|
| 578 |  | 
|---|
| 579 | The Dial component, named 'dial, is \e anchored to the center of the main | 
|---|
| 580 | rectangle. The \c value attribute of 'dial' is set to a value based on the | 
|---|
| 581 | 'slider' horizontal position and the 'container' width. So changes to the | 
|---|
| 582 | 'slider' position will change the Dial \c value which is used in Dial to compute | 
|---|
| 583 | the rotation of the needle image. Notice this piece of code in Dial where | 
|---|
| 584 | the change in \c value modifies the position of the needle. | 
|---|
| 585 |  | 
|---|
| 586 | \snippet examples/declarative/ui-components/dialcontrol/content/Dial.qml  needle angle | 
|---|
| 587 |  | 
|---|
| 588 | This is part of the \c needleRotation that rotates the needle and causes the | 
|---|
| 589 | rotation of its shadow. \l SpringAnimation is an element that modifies the value | 
|---|
| 590 | of that rotation \e angle and mimics the oscillatory behavior of a spring, | 
|---|
| 591 | with the appropriate \e spring constant to control the acceleration and the \e | 
|---|
| 592 | damping to control how quickly the effect dies away. | 
|---|
| 593 |  | 
|---|
| 594 | The 'container' is light gray with a color gradient defined using | 
|---|
| 595 | \l GradientStop. The gradient is applied vertically. If you need a horizontal | 
|---|
| 596 | gradient then you could apply the vertical gradient and then rotate the item | 
|---|
| 597 | by 90 degrees. | 
|---|
| 598 |  | 
|---|
| 599 | The 'slider' is dark gray and also has a vertical color gradient. The most | 
|---|
| 600 | important thing about the 'slider' is that it has a MouseArea defined, which | 
|---|
| 601 | specifies a \c {drag.target} on itself along the X-axis. With minimum | 
|---|
| 602 | and maximum values on the X-axis defined. So we can click on the 'slider' and | 
|---|
| 603 | drag it left and right within the confines of the 'container'. The motion of | 
|---|
| 604 | the 'slider' will then change the \c value attribute in \e Dial as discussed | 
|---|
| 605 | already. | 
|---|
| 606 |  | 
|---|
| 607 | Also notice the use of a \c radius value for a rectangle. This produces rounded | 
|---|
| 608 | corners. That is how the 'container' and 'slider' are displayed with a | 
|---|
| 609 | pleasant rounded look. | 
|---|
| 610 |  | 
|---|
| 611 |  | 
|---|
| 612 |  | 
|---|
| 613 | */ | 
|---|
| 614 |  | 
|---|
| 615 |  | 
|---|
| 616 |  | 
|---|