State machines can be used for many purposes, but in this chapter we will only cover topics related to animation.
#include <QStateMachine> #include <QPropertyAnimation> #include <QEventTransition>
QStateMachine *machine = new QStateMachine(this); QState *s1 = new QState(); QState *s2 = new QState();
QState *s1 = new QState(); s1->assignProperty(ui->stateLabel, "text", "Current state: 1"); s1->assignProperty(ui->pushButton, "geometry", QRect(50, 200, 100, 50)); QState *s2 = new QState(); s2->assignProperty(ui->stateLabel, "text", "Current state: 2"); s2->assignProperty(ui->pushButton, "geometry", QRect(200, 50, 140, 100));
QEventTransition *t1 = new QEventTransition(ui->changeState, QEvent::MouseButtonPress); t1->setTargetState(s2); s1->addTransition(t1); QEventTransition *t2 = new QEventTransition(ui->changeState, QEvent::MouseButtonPress); T2->setTargetState(s1); s2->addTransition(t2);
machine->start()
to start running the state machine:machine->addState(s1); machine->addState(s2); machine->setInitialState(s1); machine->start();
QEventTransition *t1 = new QEventTransition(ui->changeState, QEvent::MouseButtonPress); t1->setTargetState(s2); t1->addAnimation(new QPropertyAnimation(ui->pushButton, "geometry")); s1->addTransition(t1); QEventTransition *t2 = new QEventTransition(ui->changeState, QEvent::MouseButtonPress); t2->setTargetState(s1); t2->addAnimation(new QPropertyAnimation(ui->pushButton, "geometry")); s2->addTransition(t2);
QPropertyAnimation *animation = new QPropertyAnimation(ui->pushButton, "geometry"); animation->setEasingCurve(QEasingCurve::OutBounce); QEventTransition *t1 = new QEventTransition(ui->changeState, QEvent::MouseButtonPress); t1->setTargetState(s2); t1->addAnimation(animation); s1->addTransition(t1); QEventTransition *t2 = new QEventTransition(ui->changeState, QEvent::MouseButtonPress); t2->setTargetState(s1); t2->addAnimation(animation); s2->addTransition(t2);
There are two push buttons and a label on the main window layout. The button at the top-left corner will trigger the state change when pressed, while the label at the top-right corner will change its text to show which state we are currently in, and the button below will animate according to the current state.
The QEventTransition
classes define what will trigger the transition between one state and another.
In our case, we want the state to change from state 1 to state 2 when the ui->changeState
button (the one at the upper left) is clicked. After that, we also want to change from state 2 back to state 1 when the same button is pressed again. This can be achieved by creating another event transition class and setting the target state back to state 1. Then, add these transitions to their respective states.
Instead of just assigning the properties directly to the widgets, we tell Qt to use the property animation class to smoothly interpolate the properties toward the target values. It is that simple!
There is no need to set the start value and end value, because we have already called the assignProperty()
function, which has automatically assigned the end value.
The state machine framework in Qt provides classes for creating and executing state graphs. Qt's event system is used to drive the state machines, where transitions between states can be triggered by using signals, then the slots on the other end will be invoked by the signals to perform an action, such as playing an animation.
Once you understand the basics of state machines, you can use them to do other things as well. The state graph in the state machine framework is hierarchical. Just like the animation group in the previous section, states can also be nested inside of other states:
18.224.54.136