ステートマシンのインスタンス化
動的に作成されたステートマシンもコンパイルされたステートマシンも、同じように振る舞い、同じプロパティ、ステート、データモデルなどを持つ。インスタンス化の方法が異なるだけです。SCXML ファイルから C++ で動的にステートマシンを作成するには、次のようにします:
auto *stateMachine = QScxmlStateMachine::fromFile("MyStatemachine.scxml");
または、QMLの場合です:
import QtScxml Item { property StateMachine stateMachine: scxmlLoader.stateMachine StateMachineLoader { id: scxmlLoader source: "statemachine.scxml" } }
コンパイルされたステートマシンは、C++のオブジェクトと同じようにインスタンス化することができます:
auto *stateMachine = new MyStatemachine;
または
MyStatemachine stateMachine;
コンパイルしたステートマシンをQMLで使用するには、QMLの型として登録します:
struct MyStateMachineRegistration { Q_GADGET QML_NAMED_ELEMENT(MyStateMachine) QML_FOREIGN(MyStateMachine) QML_ADDED_IN_VERSION(1, 0) };
そして、次のようにQMLでインスタンス化します:
import MyStateMachine 1.0 MyStateMachine { id: stateMachine }
ステートマシンをコンパイルするには、プロジェクトのビルドファイルに以下の行を追加する必要があります:
cmakeを使う場合:
find_package(Qt6 REQUIRED COMPONENTS Scxml)
target_link_libraries(mytarget PRIVATE Qt6::Scxml)
qt_add_statecharts(mytarget
MyStatemachine.scxml
)
qmake を使用する場合:
QT += scxml
STATECHARTS = MyStatemachine.scxml
qmakeにqscxmlcを実行させ、MyStatemachine.hとMyStatemachine.cppを生成し、プロジェクトのヘッダーとソースに適切に追加します。デフォルトでは、生成されたファイルはビルド・ディレクトリに保存されます。qmakeQSCXMLC_DIRまたは cmakeOUTPUT_DIRECTORY変数を設定して、別のディレクトリを指定できます。qmakeQSCXMLC_NAMESPACEまたは cmakeNAMESPACE変数を設定して、ステートマシンコードを C++ ネームスペースに置くことができます。
ステートマシンをインスタンス化した後、以下のように任意のステートのアクティブ・プロパティに接続できます。例えば、信号機のステートマシンに、信号が赤であることを示すステート(scxmlファイルでは便利なID "red "を持っている)がある場合、次のように書くことができる:
stateMachine->connectToState("red", [](boolactive) { と書くことができる。 qDebug() << (active ? "entered" : "exited") << "the red state"; });
そしてQMLでは
Light { id: greenLight color: "green" visible: stateMachine.green }
ステートマシンがイベントを送信したときに通知を受けたい場合は、対応するシグナルに接続します。例えば、メディアプレーヤーのステートマシンが、再生が停止したことを示すイベントを送信する場合、次のように記述します:
stateMachine->connectToEvent("playbackStopped", [](constQScxmlEvent&){ qDebug() << "Stopped!"; });
そしてQMLでは
import QtScxml EventConnection { stateMachine: stateMachine events: ["playbackStopped"] onOccurred: console.log("Stopped!") }
ステートマシンへのイベント送信も同様に簡単です:
stateMachine->submitEvent("tap", QVariantMap({ { "artist", "Fatboy Slim" }, { "title", "The Rockafeller Skank" } }));
ステートマシン内の_event.dataにマップの内容が格納され、"tap "イベントが生成されます。QMLでは
stateMachine.submitEvent("tap", { "artist": "Fatboy Slim" "title": "The Rockafeller Skank" })
注意: ステートマシンを正しく動作させるには、QEventLoop
。イベントループは、delay
属性を実装し、ネストされた(または親)ステートマシンからイベントを受信した際に、ステートマシンの処理をスケジュールするために使用されます。QMLアプリケーションやウィジェットアプリケーションでは、常にイベントループが実行されているので、余計なものは必要ありません。その他のアプリケーションでは、イベントループの処理を開始するためにQApplication::run
を呼び出す必要があります。
© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.