The Animation Framework
|
QAbstractAnimation | The base of all animations |
---|---|
QAnimationGroup | Abstract base class for groups of animations |
QEasingCurve | Easing curves for controlling animation |
QParallelAnimationGroup | Parallel group of animations |
QPauseAnimation | Pause for QSequentialAnimationGroup |
QPropertyAnimation | Animates Qt properties |
QSequentialAnimationGroup | Sequential group of animations |
QTimeLine | Timeline for controlling animations |
QVariantAnimation | Abstract base class for animations |
As mentioned in the previous section, the QPropertyAnimation class can interpolate over Qt properties. It is this class that should be used for animation of values; in fact, its superclass, QVariantAnimation, is an abstract class, and cannot be used directly.
A major reason we chose to animate Qt properties is that it presents us with freedom to animate already existing classes in the Qt API. Notably, the QWidget class (which we can also embed in a QGraphicsView) has properties for its bounds, colors, etc. Let's look at a small example:
QPushButton button("Animated Button"); button.show(); QPropertyAnimation animation(&button, "geometry"); animation.setDuration(10000); animation.setStartValue(QRect(0, 0, 100, 30)); animation.setEndValue(QRect(250, 250, 100, 30)); animation.start();
This code will move button from the top left corner of the screen to the position (250, 250) in 10 seconds (10000 milliseconds).
The example above will do a linear interpolation between the start and end value. It is also possible to set values situated between the start and end value. The interpolation will then go by these points.
QPushButton button("Animated Button"); button.show(); QPropertyAnimation animation(&button, "geometry"); animation.setDuration(10000); animation.setKeyValueAt(0, QRect(0, 0, 100, 30)); animation.setKeyValueAt(0.8, QRect(250, 250, 100, 30)); animation.setKeyValueAt(1, QRect(0, 0, 100, 30)); animation.start();
In this example, the animation will take the button to (250, 250) in 8 seconds, and then move it back to its original position in the remaining 2 seconds. The movement will be linearly interpolated between these points.
You also have the possibility to animate values of a QObject that is not declared as a Qt property. The only requirement is that this value has a setter. You can then subclass the class containing the value and declare a property that uses this setter. Note that each Qt property requires a getter, so you will need to provide a getter yourself if this is not defined.
class MyGraphicsRectItem : public QObject, public QGraphicsRectItem { Q_OBJECT Q_PROPERTY(QRectF geometry READ geometry WRITE setGeometry) };
In the above code example, we subclass QGraphicsRectItem and define a geometry property. We can now animate the widgets geometry even if QGraphicsRectItem does not provide the geometry property.
For a general introduction to the Qt property system, see its overview.
When you want to animate QGraphicsItems, you also use QPropertyAnimation. However, QGraphicsItem does not inherit QObject. A good solution is to subclass the graphics item you wish to animate. This class will then also inherit QObject. This way, QPropertyAnimation can be used for QGraphicsItems. The example below shows how this is done. Another possibility is to inherit QGraphicsWidget, which already is a QObject.
class Pixmap : public QObject, public QGraphicsPixmapItem { Q_OBJECT Q_PROPERTY(QPointF pos READ pos WRITE setPos) ...
As described in the previous section, we need to define properties that we wish to animate.
Note that QObject must be the first class inherited as the meta-object system demands this.
As mentioned, QPropertyAnimation performs an interpolation between the start and end property value. In addition to adding more key values to the animation, you can also use an easing curve. Easing curves describe a function that controls how the speed of the interpolation between 0 and 1 should be, and are useful if you want to control the speed of an animation without changing the path of the interpolation.
QPushButton button("Animated Button"); button.show(); QPropertyAnimation animation(&button, "geometry"); animation.setDuration(3000); animation.setStartValue(QRect(0, 0, 100, 30)); animation.setEndValue(QRect(250, 250, 100, 30)); animation.setEasingCurve(QEasingCurve::OutBounce); animation.start();
Here the animation will follow a curve that makes it bounce like a ball as if it was dropped from the start to the end position. QEasingCurve has a large collection of curves for you to choose from. These are defined by the QEasingCurve::Type enum. If you are in need of another curve, you can also implement one yourself, and register it with QEasingCurve.
An application will often contain more than one animation. For instance, you might want to move more than one graphics item simultaneously or move them in sequence after each other.
The subclasses of QAnimationGroup (QSequentialAnimationGroup and QParallelAnimationGroup) are containers for other animations so that these animations can be animated either in sequence or parallel. The QAnimationGroup is an example of an animation that does not animate properties, but it gets notified of time changes periodically. This enables it to forward those time changes to its contained animations, and thereby controlling when its animations are played.
Let's look at code examples that use both QSequentialAnimationGroup and QParallelAnimationGroup, starting off with the latter.
QPushButton *bonnie = new QPushButton("Bonnie"); bonnie->show(); QPushButton *clyde = new QPushButton("Clyde"); clyde->show(); QPropertyAnimation *anim1 = new QPropertyAnimation(bonnie, "geometry"); // Set up anim1 QPropertyAnimation *anim2 = new QPropertyAnimation(clyde, "geometry"); // Set up anim2 QParallelAnimationGroup *group = new QParallelAnimationGroup; group->addAnimation(anim1); group->addAnimation(anim2); group->start();
A parallel group plays more than one animation at the same time. Calling its start() function will start all animations it governs.
QPushButton button("Animated Button"); button.show(); QPropertyAnimation anim1(&button, "geometry"); anim1.setDuration(3000); anim1.setStartValue(QRect(0, 0, 100, 30)); anim1.setEndValue(QRect(500, 500, 100, 30)); QPropertyAnimation anim2(&button, "geometry"); anim2.setDuration(3000); anim2.setStartValue(QRect(500, 500, 100, 30)); anim2.setEndValue(QRect(1000, 500, 100, 30)); QSequentialAnimationGroup group; group.addAnimation(&anim1); group.addAnimation(&anim2); group.start();
As you no doubt have guessed, QSequentialAnimationGroup plays its animations in sequence. It starts the next animation in the list after the previous is finished.
Since an animation group is an animation itself, you can add it to another group. This way, you can build a tree structure of animations which specifies when the animations are played in relation to each other.
When using a state machine, we can associate one or more animations to a transition between states using a QSignalTransition or QEventTransition class. These classes are both derived from QAbstractTransition, which defines the convenience function addAnimation() that enables the appending of one or more animations triggered when the transition occurs.
We also have the possibility to associate properties with the states rather than setting the start and end values ourselves. Below is a complete code example that animates the geometry of a QPushButton.
QPushButton *button = new QPushButton("Animated Button"); button->show(); QStateMachine *machine = new QStateMachine; QState *state1 = new QState(machine); state1->assignProperty(button, "geometry", QRect(0, 0, 100, 30)); machine->setInitialState(state1); QState *state2 = new QState(machine); state2->assignProperty(button, "geometry", QRect(250, 250, 100, 30)); QSignalTransition *transition1 = state1->addTransition(button, SIGNAL(clicked()), state2); transition1->addAnimation(new QPropertyAnimation(button, "geometry")); QSignalTransition *transition2 = state2->addTransition(button, SIGNAL(clicked()), state1); transition2->addAnimation(new QPropertyAnimation(button, "geometry")); machine->start();
For a more comprehensive example of how to use the state machine framework for animations, see the states example (it lives in the examples/animation/states directory).
Cette page est une traduction d'une page de la documentation de Qt, écrite par Nokia Corporation and/or its subsidiary(-ies). Les éventuels problèmes résultant d'une mauvaise traduction ne sont pas imputables à Nokia. | Qt 4.6-snapshot | |
Copyright © 2012 Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon, vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts. Cette page est déposée à la SACD. | ||
Vous avez déniché une erreur ? Un bug ? Une redirection cassée ? Ou tout autre problème, quel qu'il soit ? Ou bien vous désirez participer à ce projet de traduction ? N'hésitez pas à nous contacter ou par MP ! |
Copyright © 2000-2012 - www.developpez.com