Instancier des machines d'état
Les machines à états créées dynamiquement et compilées se comportent de la même manière, ont les mêmes propriétés, les mêmes états, le même modèle de données, etc. Elles ne diffèrent que par la manière dont elles sont instanciées. Pour créer dynamiquement une machine à états en C++ à partir d'un fichier SCXML, vous pouvez utiliser :
auto *stateMachine = QScxmlStateMachine::fromFile("MyStatemachine.scxml");
Ou, en QML :
import QtScxml Item { property StateMachine stateMachine: scxmlLoader.stateMachine StateMachineLoader { id: scxmlLoader source: "statemachine.scxml" } }
Une machine d'état compilée peut être instanciée de la même manière que n'importe quel objet C++ :
auto *stateMachine = new MyStatemachine;
Ou :
MyStatemachine stateMachine;
Pour utiliser une machine à états compilée en QML, vous pouvez l'enregistrer en tant que type QML :
struct MyStateMachineRegistration { Q_GADGET QML_NAMED_ELEMENT(MyStateMachine) QML_FOREIGN(MyStateMachine) QML_ADDED_IN_VERSION(1, 0) };
Ensuite, vous pouvez l'instancier en QML, comme ceci :
import MyStateMachine 1.0 MyStateMachine { id: stateMachine }
Pour compiler une machine à états, les lignes suivantes doivent être ajoutées au fichier de compilation du projet :
Lorsque vous utilisez cmake :
find_package(Qt6 REQUIRED COMPONENTS Scxml)
target_link_libraries(mytarget PRIVATE Qt6::Scxml)qt_add_statecharts(mytarget
MyStatemachine.scxml
)Lors de l'utilisation de qmake :
QT += scxml
STATECHARTS = MyStatemachine.scxml
Ceci demandera à qmake d'exécuter qscxmlc qui génère MyStatemachine.h et MyStatemachine.cpp, et les ajoute de manière appropriée aux en-têtes et aux sources du projet. Par défaut, les fichiers générés sont enregistrés dans le répertoire de construction. La variable qmake QSCXMLC_DIR ou cmake OUTPUT_DIRECTORY peut être définie pour spécifier un autre répertoire. La variable qmake QSCXMLC_NAMESPACE ou cmake NAMESPACE peut être définie pour placer le code de la machine à états dans un espace de noms C++.
Après avoir instancié une machine à états, vous pouvez vous connecter à la propriété active de n'importe quel état de la manière suivante. Par exemple, si la machine à états d'un feu de circulation a un état indiquant que le feu est rouge (qui a l'identifiant pratique "red" dans le fichier scxml), vous pouvez écrire :
stateMachine->connectToState("red", [](bool active) { qDebug() << (active ? "entered" : "exited") << "the red state"; }) ;
Et en QML :
Light { id: greenLight color: "green" visible: stateMachine.green }
Si vous souhaitez être informé lorsqu'une machine à états envoie un événement, vous pouvez vous connecter au signal correspondant. Par exemple, pour une machine d'état de lecteur multimédia qui indique que la lecture s'est arrêtée en envoyant un événement, vous pouvez écrire :
stateMachine->connectToEvent("playbackStopped", [](const QScxmlEvent &){ qDebug() << "Stopped!"; }) ;
Et en QML :
import QtScxml EventConnection { stateMachine: stateMachine events: ["playbackStopped"] onOccurred: console.log("Stopped!") }
L'envoi d'événements à une machine à états est tout aussi simple :
stateMachine->submitEvent("tap", QVariantMap({ { "artist", "Fatboy Slim" }, { "title", "The Rockafeller Skank" } }));
Cela génère un événement "tap" avec le contenu de la carte disponible dans _event.data à l'intérieur de la machine à états. En QML :
stateMachine.submitEvent("tap", { "artist": "Fatboy Slim" "title": "The Rockafeller Skank" })
Note : Une machine à états a besoin d'un QEventLoop pour fonctionner correctement. La boucle d'événement est utilisée pour mettre en œuvre l'attribut delay pour les événements et pour programmer le traitement d'une machine à états lorsque des événements sont reçus de machines à états imbriquées (ou parentes). Une application QML ou une application widget aura toujours une boucle d'événements en cours d'exécution, donc rien de plus n'est nécessaire. Pour les autres applications, QApplication::run devra être appelé pour démarrer le traitement de la boucle d'événements.
© 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.