はじめに
Qt 4.
Qtのステートマシンフレームワークは、
- ・
ステートチャートコンパイラ - SCXML記述をQtステートマシンフレームワークのC++コードに変換するコンパイラ
(scc、 State Chart Compiler)。 - ・
QtScript用 (QScxmlを利用) - ・
WebKitベースのブラウザ用 - Qt Labs BlogsのページではQt Webkit, Arora, Safari, Chromeなどを使って、
実際にデモを動かす ことができます。
そしてさらに、
今回紹介するアニメーションプログラムのソースリストはこちらからダウンロードしてください。
examples.zip
ステートマシンフレームワークのクラス
図1は、

クラス名 | 機能概要 |
---|---|
QStateMachine | ひとつの階層型有限状態機械。 |
QState | 状態機械中の状態で、 |
QFinalState | 状態機械中の終了状態。 |
QHistoryState | 前の活性化された副状態への復帰に用いる。 |
QEventTransition | Qtのイベント対するQObjectに特化した遷移で、 |
QKeyEventTransition | キーイベントによって引き起される遷移。 |
QMouseEventTransition | マウスイベントによって引き起される遷移。 |
QSignalTransition | Qtのシグナルによって引き起される遷移。 |
アニメーションの書き換え
詳しい説明は次回に回し、
図2は、

startState状態は、
- ボタンのテキストに "Start" をセットする。
- 3つのボタンの位置を (startX, y) にセットし、
位置を左端にする。
endState状態は、
- ボタンのテキストに"Reset"をセットする。
- 3つのボタンの位置を (startX, y) にセットし、
位置を左端にする。
movingBallTransition遷移は、
resetTransition遷移は、
前回の説明で補足したように、
これを実行させた模様は次の動画のようになります。
では、
1: #include <QApplication>
2: #include <QGraphicsView>
3: #include <QGraphicsScene>
4: #include <QGraphicsPixmapItem>
5: #include <QPropertyAnimation>
6: #include <QSequentialAnimationGroup>
7: #include <QParallelAnimationGroup>
8: #include <QLayout>
9: #include <QPushButton>
10: #include <QState>
11: #include <QStateMachine>
12: #include <QSignalTransition>
10~12行で、
52: Harness::Harness()
53: : QWidget( 0 ), d_ptr( new HarnessPrivate )
54: {
55: Q_D( Harness );
56:
57: QGraphicsScene* graphicsScene = new QGraphicsScene( 0, 0, d->movingAreaSize.width(), d->movingAreaSize.height() );
58: MovableGraphicsPixmapItem* yellowBallItem = createBallItem( ":/images/YellowGlassBall.png" );
59: QSize ballSize = yellowBallItem->pixmap().size();
60: int ballSpacingY = ( d->movingAreaSize.height() - ballSize.height() * 3 ) / 4;
61: int yellowBallY = ballSpacingY;
62: yellowBallItem->setPos( d->horizontalOffset, yellowBallY );
63: graphicsScene->addItem( yellowBallItem );
64:
65: MovableGraphicsPixmapItem* greenBallItem = createBallItem( ":/images/GreenGlassBall.png" );
66: int greenBallY = yellowBallY + ballSize.height() + ballSpacingY;
67: greenBallItem->setPos( d->horizontalOffset, greenBallY );
68: graphicsScene->addItem( greenBallItem );
69:
70: MovableGraphicsPixmapItem* redBallItem = createBallItem( ":/images/RedGlassBall.png" );
71: int redBallY = greenBallY + ballSize.height() + ballSpacingY;
72: redBallItem->setPos( d->horizontalOffset, redBallY );
73: graphicsScene->addItem( redBallItem );
74:
75: QGraphicsView* graphicsView = new QGraphicsView();
76: graphicsView->setScene( graphicsScene );
77:
78: QPushButton* animateButton = new QPushButton( "Start" );
初期状態に入ると、
80: QHBoxLayout* buttonLayout = new QHBoxLayout;
81: buttonLayout->addStretch();
82: buttonLayout->addWidget( animateButton );
83:
84: QVBoxLayout* topLayout = new QVBoxLayout;
85: topLayout->addWidget( graphicsView );
86: topLayout->addLayout( buttonLayout );
87:
88: setLayout( topLayout );
89: setFixedSize( sizeHint() );
90:
91: int movableBallStartX = d->horizontalOffset;
92: int movableBallEndX = d->movingAreaSize.width() - ballSize.width() - d->horizontalOffset;
93:
94: QPropertyAnimation* yellowBallAnimation = createBallAnimation( yellowBallItem, 20 * 1000, movableBallStartX, movableBallEndX, yellowBallY );
95: QPropertyAnimation* greenBallAnimation = createBallAnimation( greenBallItem, 10 * 1000, movableBallStartX, movableBallEndX, greenBallY );
96: QPropertyAnimation* redBallAnimation = createBallAnimation( redBallItem, 10 * 1000, movableBallStartX, movableBallEndX, redBallY );
97:
98: d->ballAnimationGroup = new QParallelAnimationGroup( this );
99: d->ballAnimationGroup->addAnimation( yellowBallAnimation );
100: QSequentialAnimationGroup* sequentialAnimation = new QSequentialAnimationGroup;
101: sequentialAnimation->addAnimation( greenBallAnimation );
102: sequentialAnimation->addAnimation( redBallAnimation );
103: d->ballAnimationGroup->addAnimation( sequentialAnimation );
104:
105: QStateMachine* stateMachine = new QStateMachine( this );
状態遷移機械のインスタンスで、
107: QState* startState = new QState( stateMachine );
108: startState->assignProperty( yellowBallItem, "pos", yellowBallAnimation->startValue() );
109: startState->assignProperty( greenBallItem, "pos", greenBallAnimation->startValue() );
110: startState->assignProperty( redBallItem, "pos", redBallAnimation->startValue() );
111: startState->assignProperty( animateButton, "text", "Start" );
112: stateMachine->setInitialState( startState );
アニメーションの開始待ちを表すstartState状態のインスタンスです。メソッドassignProperty()でこの状態になったときに、
114: QState* endState = new QState( stateMachine );
115: endState->assignProperty( yellowBallItem, "pos", yellowBallAnimation->endValue() );
116: endState->assignProperty( greenBallItem, "pos", greenBallAnimation->endValue() );
117: endState->assignProperty( redBallItem, "pos", redBallAnimation->endValue() );
118: endState->assignProperty( animateButton, "text", "Reset" );
アニメーションの完了状態を表すendState状態のインスタンスで、
120: QSignalTransition* movingBallTransition = startState->addTransition( animateButton, SIGNAL( clicked() ), endState );
121: movingBallTransition->addAnimation( d->ballAnimationGroup );
startState状態にあるときに、
122: QSignalTransition* resetTransition = endState->addTransition( animateButton, SIGNAL( clicked() ), startState );
123: Q_UNUSED( resetTransition );
逆に、
125: stateMachine->start();
126: }
状態遷移機械によって動作が規定されてるので、
おわりに
Qtのステートマシンフレームワークの概要とその実際の適用例について説明しました。簡単な例ですが、