前回はステートマシーンフレームワークの経緯を説明し,
ステートマシンフレームワークの使用手順
ステートマシンフレームワークの基本的な使用手順は次のようになります。
- ①状態遷移機械の生成
QStateMachineのインスタンスを生成します。
- ②状態の生成
QStateのインスタンスが状態を表し,
コンストラクタにはQStateMachineまたはQStateのインスタンスを指定します。通常の状態では, QStateMachineを渡してQState のインスタンスを生成します。複合状態や並列状態を生成する場合には, QState のインスタンスを渡します。 - ③遷移の生成
オブジェクトのシグナル送信によって引き起される遷移の場合には,
QSignalTransitionのインスタンスを生成し, マウスとキーによる場合には, QMouseEventTransitionやQKeyEventTransitionのインスタンスを生成して, 遷移を生成し, QState::addTransition() で, 状態に遷移を設定します。 以下のような,
簡単にトランジションを設定できるメソッドも用意されています。 QState::addTransition( QObject* sender, const char* signal, QAbstractState* target )
QAbstractTransition::addAnimation()で必要に応じてアニメーションを付加します。
- ④初期状態の設定
QStateMachine::setInitialState()で,
初期状態となるQStateのインスタンスを設定します。複合状態や並列状態の場合には, 入れ子になった各状態に対して, QState::setInitialState()で初期状態を設定します。 - ⑤状態遷移機械の起動
QStateMachineのインスタンスに対してstart() を呼び出します。
基本的なステートマシンフレームワークの適用例
ステートマシンフレームワークのサンプルプログラムがQtに付属しています。まず,
このサンプルプログラムを動かすと,
状態遷移図は図2のようになります。前回のサンプルプログラムの状態遷移図と本質的には同じです。
サンプルプログラムを見ていきましょう。
リスト1 Two-way Button Example
1: #include <QtGui>
2:
3: int main(int argc, char **argv)
4: {
5: QApplication app(argc, argv);
6: QPushButton button;
7: QStateMachine machine;
「状態遷移機械の生成」
9: QState *off = new QState();
10: off->assignProperty(&button, "text", "Off");
11: off->setObjectName("off");
12:
13: QState *on = new QState();
14: on>setObjectName("on");
15: on->assignProperty(&button, "text", "On");
「状態の生成」
17: off->addTransition(&button, SIGNAL(clicked()), on);
18: on->addTransition(&button, SIGNAL(clicked()), off);
状態に,
- void addTransition(QAbstractTransition* transition)
QSignalTransition,
QMouseEventTransitionやQKeyEventTransitionのインスタンスを生成してから設定します。リスト1の17~18行は, 以下のように書き換えられます。 QSignalTransition *fromOfftoOnTransition = new QSignalTransition(&button, SIGNAL(clicked()), off); fromOfftoOnTransition->setTargetState(on); QSignalTransition *fromOntoOffTransition = new QSignalTransition(&button, SIGNAL(clicked()), on); fromOntoOffTransition->setTargetState(off);
QSignalTransitionのインスタンスの所有者は,
offまたはonのQStateインスタンスになることに注意しましょう。 - QSignalTransition *addTransition(QObject *sender, const char *signal, QAbstractState *target)
このサンプルプログラムで使われているメソッドです。signalにはQObject::connect()と同様に,
マクロSIGNAL()によって正規化したシグナルのシグネチャ文字列を渡します。 - QAbstractTransition *addTransition(QAbstractState *target)
無条件遷移で,
遷移のためのトリガーはなく, 元状態からtargetに指定した状態にすぐに遷移します。
20: machine.addState(off);
21: machine.addState(on);
「状態の生成」
-
9: QState *off = new QState(&machine); 13: QState *on = new QState(&machine);
23: machine.setInitialState(off);
「初期状態の設定」
24: machine.start();
「状態遷移機械の起動」
26: button.resize(100, 50);
27: button.show();
28: return app.exec();
29: }