ステートマシンのインスタンス化
動的に作成されたステートマシンも、コンパイルされたステートマシンも、動作やプロパティ、状態、データモデルなどはすべて同じです。異なるのは、インスタンス化の方法だけです。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 += scxmlSTATECHARTS = MyStatemachine.scxmlこれにより、qmakeはqscxmlcを実行し、MyStatemachine.hおよびMyStatemachine.cppを生成して、それらをプロジェクトのヘッダーおよびソースに適切に追加します。デフォルトでは、生成されたファイルはビルドディレクトリに保存されます。 qmakeのQSCXMLC_DIR変数またはcmakeのOUTPUT_DIRECTORY変数を設定することで、別のディレクトリを指定できます。また、qmakeのQSCXMLC_NAMESPACE変数またはcmakeのNAMESPACE変数を設定することで、ステートマシンコードをC++のネームスペース内に配置できます。
ステートマシンをインスタンス化した後、次のように任意のステートのアクティブプロパティに接続できます。たとえば、信号機のステートマシンに、信号が赤であることを示すステートがある場合(scxml ファイルでは「red」という便利な ID が付いています)、次のように記述できます:
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" }
}));これにより、「tap」イベントが生成され、ステートマシン内の `_event.data` でマップの内容が利用可能になります。QMLでは:
stateMachine.submitEvent("tap", {
"artist": "Fatboy Slim"
"title": "The Rockafeller Skank"
})注:ステートマシンが 正しく動作するには、QEventLoop が必要です。イベントループは、イベントに対するdelay 属性を実装したり、ネストされた(または親の)ステートマシンからイベントを受信した際にステートマシンの処理をスケジュールしたりするために使用されます。QMLアプリケーションやウィジェットアプリケーションでは常にイベントループが実行されているため、追加の設定は不要です。 その他のアプリケーションの場合、イベントループの処理を開始するには、QApplication::run を呼び出す必要があります。
© 2026 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.