source: trunk/doc/src/frameworks-technologies/animation.qdoc@ 568

Last change on this file since 568 was 561, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.6.1 sources.

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