1/**************************************************************************** 2** 3** Copyright (C) 2015 The Qt Company Ltd. 4** Contact: http://www.qt.io/licensing/ 5** 6** This file is part of the documentation of the Qt Toolkit. 7** 8** $QT_BEGIN_LICENSE:FDL$ 9** Commercial License Usage 10** Licensees holding valid commercial Qt licenses may use this file in 11** accordance with the commercial license agreement provided with the 12** Software or, alternatively, in accordance with the terms contained in 13** a written agreement between you and The Qt Company. For licensing terms 14** and conditions see http://www.qt.io/terms-conditions. For further 15** information use the contact form at http://www.qt.io/contact-us. 16** 17** GNU Free Documentation License Usage 18** Alternatively, this file may be used under the terms of the GNU Free 19** Documentation License version 1.3 as published by the Free Software 20** Foundation and appearing in the file included in the packaging of 21** this file. Please review the following information to ensure 22** the GNU Free Documentation License version 1.3 requirements 23** will be met: http://www.gnu.org/copyleft/fdl.html. 24** $QT_END_LICENSE$ 25** 26****************************************************************************/ 27 28/*! 29 \group animation 30 \title Animation Framework 31*/ 32 33/*! 34 \page animation-overview.html 35 \title The Animation Framework 36 \ingroup qt-gui-concepts 37 38 \brief An overview of the Animation Framework 39 40 \ingroup frameworks-technologies 41 42 \keyword Animation 43 44 The animation framework is part of the Kinetic project, and aims 45 to provide an easy way for creating animated and smooth GUI's. By 46 animating Qt properties, the framework provides great freedom for 47 animating widgets and other \l{QObject}s. The framework can also 48 be used with the Graphics View framework. 49 50 In this overview, we explain the basics of its architecture. We 51 also show examples of the most common techniques that the 52 framework allows for animating QObjects and graphics items. 53 54 \tableofcontents 55 56 \section1 The Animation Architecture 57 58 We will in this section take a high-level look at the animation 59 framework's architecture and how it is used to animate Qt 60 properties. The following diagram shows the most important classes 61 in the animation framework. 62 63 \image animations-architecture.png 64 65 The animation framework foundation consists of the base class 66 QAbstractAnimation, and its two subclasses QVariantAnimation and 67 QAnimationGroup. QAbstractAnimation is the ancestor of all 68 animations. It represents basic properties that are common for all 69 animations in the framework; notably, the ability to start, stop, 70 and pause an animation. It is also receives the time change 71 notifications. 72 73 The animation framework further provides the QPropertyAnimation 74 class, which inherits QVariantAnimation and performs animation of 75 a Qt property, which is part of Qt's \l{Meta-Object 76 System}{meta-object system}. The class performs an interpolation 77 over the property using an easing curve. So when you want to 78 animate a value, you can declare it as a property and make your 79 class a QObject. Note that this gives us great freedom in 80 animating already existing widgets and other \l{QObject}s. 81 82 Complex animations can be constructed by building a tree structure 83 of \l{QAbstractAnimation}s. The tree is built by using 84 \l{QAnimationGroup}s, which function as containers for other 85 animations. Note also that the groups are subclasses of 86 QAbstractAnimation, so groups can themselves contain other groups. 87 88 The animation framework can be used on its own, but is also 89 designed to be part of the state machine framework (See the 90 \l{The State Machine Framework}{state machine framework} for an 91 introduction to the Qt state machine). The state machine provides 92 a special state that can play an animation. A QState can also set 93 properties when the state is entered or exited, and this special 94 animation state will interpolate between these values when given a 95 QPropertyAnimation. We will look more closely at this later. 96 97 Behind the scenes, the animations are controlled by a global 98 timer, which sends \l{QAbstractAnimation::updateCurrentTime()}{updates} to 99 all animations that are playing. 100 101 For detailed descriptions of the classes' function and roles in 102 the framework, please look up their class descriptions. 103 104 \section1 Classes in the Animation Framework 105 106 These classes provide a framework for creating both simple and complex 107 animations. 108 109 \annotatedlist animation 110 111 \section1 Animating Qt Properties 112 113 As mentioned in the previous section, the QPropertyAnimation class 114 can interpolate over Qt properties. It is this class that should 115 be used for animation of values; in fact, its superclass, 116 QVariantAnimation, is an abstract class, and cannot be used 117 directly. 118 119 A major reason we chose to animate Qt properties is that it 120 presents us with freedom to animate already existing classes in 121 the Qt API. Notably, the QWidget class (which we can also embed in 122 a QGraphicsView) has properties for its bounds, colors, etc. 123 Let's look at a small example: 124 125 \code 126 QPushButton button("Animated Button"); 127 button.show(); 128 129 QPropertyAnimation animation(&button, "geometry"); 130 animation.setDuration(10000); 131 animation.setStartValue(QRect(0, 0, 100, 30)); 132 animation.setEndValue(QRect(250, 250, 100, 30)); 133 134 animation.start(); 135 \endcode 136 137 This code will move \c button from the top left corner of the 138 screen to the position (250, 250) in 10 seconds (10000 milliseconds). 139 140 The example above will do a linear interpolation between the 141 start and end value. It is also possible to set values 142 situated between the start and end value. The interpolation 143 will then go by these points. 144 145 \code 146 QPushButton button("Animated Button"); 147 button.show(); 148 149 QPropertyAnimation animation(&button, "geometry"); 150 animation.setDuration(10000); 151 152 animation.setKeyValueAt(0, QRect(0, 0, 100, 30)); 153 animation.setKeyValueAt(0.8, QRect(250, 250, 100, 30)); 154 animation.setKeyValueAt(1, QRect(0, 0, 100, 30)); 155 156 animation.start(); 157 \endcode 158 159 In this example, the animation will take the button to (250, 250) 160 in 8 seconds, and then move it back to its original position in 161 the remaining 2 seconds. The movement will be linearly 162 interpolated between these points. 163 164 You also have the possibility to animate values of a QObject 165 that is not declared as a Qt property. The only requirement is 166 that this value has a setter. You can then subclass the class 167 containing the value and declare a property that uses this setter. 168 Note that each Qt property requires a getter, so you will need to 169 provide a getter yourself if this is not defined. 170 171 \code 172 class MyGraphicsRectItem : public QObject, public QGraphicsRectItem 173 { 174 Q_OBJECT 175 Q_PROPERTY(QRectF geometry READ geometry WRITE setGeometry) 176 }; 177 \endcode 178 179 In the above code example, we subclass QGraphicsRectItem and 180 define a geometry property. We can now animate the widgets 181 geometry even if QGraphicsRectItem does not provide the geometry 182 property. 183 184 For a general introduction to the Qt property system, see its 185 \l{Qt's Property System}{overview}. 186 187 \section1 Animations and the Graphics View Framework 188 189 When you want to animate \l{QGraphicsItem}s, you also use 190 QPropertyAnimation. However, QGraphicsItem does not inherit QObject. 191 A good solution is to subclass the graphics item you wish to animate. 192 This class will then also inherit QObject. 193 This way, QPropertyAnimation can be used for \l{QGraphicsItem}s. 194 The example below shows how this is done. Another possibility is 195 to inherit QGraphicsWidget, which already is a QObject. 196 197 \code 198 class Pixmap : public QObject, public QGraphicsPixmapItem 199 { 200 Q_OBJECT 201 Q_PROPERTY(QPointF pos READ pos WRITE setPos) 202 ... 203 \endcode 204 205 As described in the previous section, we need to define 206 properties that we wish to animate. 207 208 Note that QObject must be the first class inherited as the 209 meta-object system demands this. 210 211 \section1 Easing Curves 212 213 As mentioned, QPropertyAnimation performs an interpolation between 214 the start and end property value. In addition to adding more key 215 values to the animation, you can also use an easing curve. Easing 216 curves describe a function that controls how the speed of the 217 interpolation between 0 and 1 should be, and are useful if you 218 want to control the speed of an animation without changing the 219 path of the interpolation. 220 221 \code 222 QPushButton button("Animated Button"); 223 button.show(); 224 225 QPropertyAnimation animation(&button, "geometry"); 226 animation.setDuration(3000); 227 animation.setStartValue(QRect(0, 0, 100, 30)); 228 animation.setEndValue(QRect(250, 250, 100, 30)); 229 230 animation.setEasingCurve(QEasingCurve::OutBounce); 231 232 animation.start(); 233 \endcode 234 235 Here the animation will follow a curve that makes it bounce like a 236 ball as if it was dropped from the start to the end position. 237 QEasingCurve has a large collection of curves for you to choose 238 from. These are defined by the QEasingCurve::Type enum. If you are 239 in need of another curve, you can also implement one yourself, and 240 register it with QEasingCurve. 241 242 \omit Drop this for the first Lab release 243 (Example of custom easing curve (without the actual impl of 244 the function I expect) 245 \endomit 246 247 \section1 Putting Animations Together 248 249 An application will often contain more than one animation. For 250 instance, you might want to move more than one graphics item 251 simultaneously or move them in sequence after each other. 252 253 The subclasses of QAnimationGroup (QSequentialAnimationGroup and 254 QParallelAnimationGroup) are containers for other animations so 255 that these animations can be animated either in sequence or 256 parallel. The QAnimationGroup is an example of an animation that 257 does not animate properties, but it gets notified of time changes 258 periodically. This enables it to forward those time changes to its 259 contained animations, and thereby controlling when its animations 260 are played. 261 262 Let's look at code examples that use both 263 QSequentialAnimationGroup and QParallelAnimationGroup, starting 264 off with the latter. 265 266 \code 267 QPushButton *bonnie = new QPushButton("Bonnie"); 268 bonnie->show(); 269 270 QPushButton *clyde = new QPushButton("Clyde"); 271 clyde->show(); 272 273 QPropertyAnimation *anim1 = new QPropertyAnimation(bonnie, "geometry"); 274 // Set up anim1 275 276 QPropertyAnimation *anim2 = new QPropertyAnimation(clyde, "geometry"); 277 // Set up anim2 278 279 QParallelAnimationGroup *group = new QParallelAnimationGroup; 280 group->addAnimation(anim1); 281 group->addAnimation(anim2); 282 283 group->start(); 284 \endcode 285 286 A parallel group plays more than one animation at the same time. 287 Calling its \l{QAbstractAnimation::}{start()} function will start 288 all animations it governs. 289 290 \code 291 QPushButton button("Animated Button"); 292 button.show(); 293 294 QPropertyAnimation anim1(&button, "geometry"); 295 anim1.setDuration(3000); 296 anim1.setStartValue(QRect(0, 0, 100, 30)); 297 anim1.setEndValue(QRect(500, 500, 100, 30)); 298 299 QPropertyAnimation anim2(&button, "geometry"); 300 anim2.setDuration(3000); 301 anim2.setStartValue(QRect(500, 500, 100, 30)); 302 anim2.setEndValue(QRect(1000, 500, 100, 30)); 303 304 QSequentialAnimationGroup group; 305 306 group.addAnimation(&anim1); 307 group.addAnimation(&anim2); 308 309 group.start(); 310 \endcode 311 312 As you no doubt have guessed, QSequentialAnimationGroup plays 313 its animations in sequence. It starts the next animation in 314 the list after the previous is finished. 315 316 Since an animation group is an animation itself, you can add 317 it to another group. This way, you can build a tree structure 318 of animations which specifies when the animations are played 319 in relation to each other. 320 321 \section1 Animations and States 322 323 When using a \l{The State Machine Framework}{state machine}, we 324 can associate one or more animations to a transition between states 325 using a QSignalTransition or QEventTransition class. These classes 326 are both derived from QAbstractTransition, which defines the 327 convenience function \l{QAbstractTransition::}{addAnimation()} that 328 enables the appending of one or more animations triggered when the 329 transition occurs. 330 331 We also have the possibility to associate properties with the 332 states rather than setting the start and end values ourselves. 333 Below is a complete code example that animates the geometry of a 334 QPushButton. 335 336 \code 337 QPushButton *button = new QPushButton("Animated Button"); 338 button->show(); 339 340 QStateMachine *machine = new QStateMachine; 341 342 QState *state1 = new QState(machine); 343 state1->assignProperty(button, "geometry", QRect(0, 0, 100, 30)); 344 machine->setInitialState(state1); 345 346 QState *state2 = new QState(machine); 347 state2->assignProperty(button, "geometry", QRect(250, 250, 100, 30)); 348 349 QSignalTransition *transition1 = state1->addTransition(button, 350 SIGNAL(clicked()), state2); 351 transition1->addAnimation(new QPropertyAnimation(button, "geometry")); 352 353 QSignalTransition *transition2 = state2->addTransition(button, 354 SIGNAL(clicked()), state1); 355 transition2->addAnimation(new QPropertyAnimation(button, "geometry")); 356 357 machine->start(); 358 \endcode 359 360 For a more comprehensive example of how to use the state machine 361 framework for animations, see the states example (it lives in the 362 \c{examples/animation/states} directory). 363*/ 364 365