States Example▲
The example demonstrates how QStateMachine states can be used to animate properties of widgets. There are three states in the application that can be sequentially triggered by a button. The button initiates state transitions that animate the properties of the application widgets.
The main() Function▲
int
main(int
argc, char
*
argv[])
{
Q_INIT_RESOURCE(states);
QApplication app(argc, argv);
// Text edit and button
QTextEdit *
edit =
new
QTextEdit;
edit-&
gt;setText("asdf lkjha yuoiqwe asd iuaysd u iasyd uiy "
"asdf lkjha yuoiqwe asd iuaysd u iasyd uiy "
"asdf lkjha yuoiqwe asd iuaysd u iasyd uiy "
"asdf lkjha yuoiqwe asd iuaysd u iasyd uiy!"
);
QPushButton *
button =
new
QPushButton;
QGraphicsProxyWidget *
buttonProxy =
new
QGraphicsProxyWidget;
buttonProxy-&
gt;setWidget(button);
QGraphicsProxyWidget *
editProxy =
new
QGraphicsProxyWidget;
editProxy-&
gt;setWidget(edit);
QGroupBox *
box =
new
QGroupBox;
box-&
gt;setFlat(true
);
box-&
gt;setTitle("Options"
);
QVBoxLayout *
layout2 =
new
QVBoxLayout;
box-&
gt;setLayout(layout2);
layout2-&
gt;addWidget(new
QRadioButton("Herring"
));
layout2-&
gt;addWidget(new
QRadioButton("Blue Parrot"
));
layout2-&
gt;addWidget(new
QRadioButton("Petunias"
));
layout2-&
gt;addStretch();
QGraphicsProxyWidget *
boxProxy =
new
QGraphicsProxyWidget;
boxProxy-&
gt;setWidget(box);
// Parent widget
QGraphicsWidget *
widget =
new
QGraphicsWidget;
QGraphicsLinearLayout *
layout =
new
QGraphicsLinearLayout(Qt::
Vertical, widget);
layout-&
gt;addItem(editProxy);
layout-&
gt;addItem(buttonProxy);
widget-&
gt;setLayout(layout);
Pixmap *
p1 =
new
Pixmap(QPixmap(":/digikam.png"
));
Pixmap *
p2 =
new
Pixmap(QPixmap(":/akregator.png"
));
Pixmap *
p3 =
new
Pixmap(QPixmap(":/accessories-dictionary.png"
));
Pixmap *
p4 =
new
Pixmap(QPixmap(":/k3b.png"
));
Pixmap *
p5 =
new
Pixmap(QPixmap(":/help-browser.png"
));
Pixmap *
p6 =
new
Pixmap(QPixmap(":/kchart.png"
));
QGraphicsScene scene(0
, 0
, 400
, 300
);
scene.setBackgroundBrush(scene.palette().window());
scene.addItem(widget);
scene.addItem(boxProxy);
scene.addItem(p1);
scene.addItem(p2);
scene.addItem(p3);
scene.addItem(p4);
scene.addItem(p5);
scene.addItem(p6);
The widgets are created and added to the QGraphicsScene. The Pixmap class is also defined in the example. It extends QGraphicsPixmapItem so that its position can be read and written as Qt properties.
QStateMachine machine;
QState *
state1 =
new
QState(&
amp;machine);
QState *
state2 =
new
QState(&
amp;machine);
QState *
state3 =
new
QState(&
amp;machine);
machine.setInitialState(state1);
The state machine and the states are created.

// State 1
state1-&
gt;assignProperty(button, "text"
, "Switch to state 2"
);
state1-&
gt;assignProperty(widget, "geometry"
, QRectF(0
, 0
, 400
, 150
));
state1-&
gt;assignProperty(box, "geometry"
, QRect(-
200
, 150
, 200
, 150
));
state1-&
gt;assignProperty(p1, "pos"
, QPointF(68
, 200
)); // 185));
state1-&
gt;assignProperty(p2, "pos"
, QPointF(168
, 200
)); // 185));
state1-&
gt;assignProperty(p3, "pos"
, QPointF(268
, 200
)); // 185));
state1-&
gt;assignProperty(p4, "pos"
, QPointF(68
-
150
, 48
-
150
));
state1-&
gt;assignProperty(p5, "pos"
, QPointF(168
, 48
-
150
));
state1-&
gt;assignProperty(p6, "pos"
, QPointF(268
+
150
, 48
-
150
));
state1-&
gt;assignProperty(p1, "rotation"
, qreal(0
));
state1-&
gt;assignProperty(p2, "rotation"
, qreal(0
));
state1-&
gt;assignProperty(p3, "rotation"
, qreal(0
));
state1-&
gt;assignProperty(p4, "rotation"
, qreal(-
270
));
state1-&
gt;assignProperty(p5, "rotation"
, qreal(-
90
));
state1-&
gt;assignProperty(p6, "rotation"
, qreal(270
));
state1-&
gt;assignProperty(boxProxy, "opacity"
, qreal(0
));
state1-&
gt;assignProperty(p1, "opacity"
, qreal(1
));
state1-&
gt;assignProperty(p2, "opacity"
, qreal(1
));
state1-&
gt;assignProperty(p3, "opacity"
, qreal(1
));
state1-&
gt;assignProperty(p4, "opacity"
, qreal(0
));
state1-&
gt;assignProperty(p5, "opacity"
, qreal(0
));
state1-&
gt;assignProperty(p6, "opacity"
, qreal(0
));
Each state is assigned the object properties that they will apply.
QAbstractTransition *
t1 =
state1-&
gt;addTransition(button, &
amp;QAbstractButton::
clicked, state2);
QSequentialAnimationGroup *
animation1SubGroup =
new
QSequentialAnimationGroup;
animation1SubGroup-&
gt;addPause(250
);
animation1SubGroup-&
gt;addAnimation(new
QPropertyAnimation(box, "geometry"
));
t1-&
gt;addAnimation(animation1SubGroup);
t1-&
gt;addAnimation(new
QPropertyAnimation(widget, "geometry"
));
t1-&
gt;addAnimation(new
QPropertyAnimation(p1, "pos"
));
t1-&
gt;addAnimation(new
QPropertyAnimation(p2, "pos"
));
t1-&
gt;addAnimation(new
QPropertyAnimation(p3, "pos"
));
t1-&
gt;addAnimation(new
QPropertyAnimation(p4, "pos"
));
t1-&
gt;addAnimation(new
QPropertyAnimation(p5, "pos"
));
t1-&
gt;addAnimation(new
QPropertyAnimation(p6, "pos"
));
t1-&
gt;addAnimation(new
QPropertyAnimation(p1, "rotation"
));
t1-&
gt;addAnimation(new
QPropertyAnimation(p2, "rotation"
));
t1-&
gt;addAnimation(new
QPropertyAnimation(p3, "rotation"
));
t1-&
gt;addAnimation(new
QPropertyAnimation(p4, "rotation"
));
t1-&
gt;addAnimation(new
QPropertyAnimation(p5, "rotation"
));
t1-&
gt;addAnimation(new
QPropertyAnimation(p6, "rotation"
));
t1-&
gt;addAnimation(new
QPropertyAnimation(p1, "opacity"
));
t1-&
gt;addAnimation(new
QPropertyAnimation(p2, "opacity"
));
t1-&
gt;addAnimation(new
QPropertyAnimation(p3, "opacity"
));
t1-&
gt;addAnimation(new
QPropertyAnimation(p4, "opacity"
));
t1-&
gt;addAnimation(new
QPropertyAnimation(p5, "opacity"
));
t1-&
gt;addAnimation(new
QPropertyAnimation(p6, "opacity"
));
The state transitions are created with the trigger of the button click. For each property, a QPropertyAnimation is created that interpolates between the property values.
machine.start();
GraphicsView view(&
amp;scene);
view.show();
return
app.exec();
The state machine is started and the scene is assigned to a GraphicsView.