TaskTree Traffic Light
Démontre comment implémenter le comportement d'une machine d'état en utilisant TaskTree à travers une simulation de feux tricolores.
Le Traffic Light de TaskTree est une implémentation alternative pour les exemples de Traffic Light de Qt SCXML et Qt State Machine.

L'application se compose de trois éléments principaux :
- Un widget
TrafficLightqui affiche l'état actuel. - Une recette
TaskTreequi contrôle les transitions d'état. - Un
GlueInterfacequi synchronise l'interface utilisateur avec la machine à états.
Les sections suivantes décrivent plus en détail le code de l'exemple.
Classe d'aide Glue
La classe GlueInterface assure une séparation nette entre l'interface utilisateur et la logique opérationnelle.
enum class Light { Off = 0, Red = 1 << 0, Yellow = 1 << 1, Green = 1 << 2, }; Q_DECLARE_FLAGS(Lights, Light) Q_DECLARE_OPERATORS_FOR_FLAGS(Lights) class GlueInterface final : public QObject { Q_OBJECT public: // operational logic -> GUI void setLights(Lights lights) { emit lightsChanged(lights); } // GUI -> operational logic void smash() { emit smashed(); } void repair() { emit repaired(); } signals: void lightsChanged(Lights lights); void smashed(); void repaired(); };
La classe GlueInterface fournit les méthodes d'interface suivantes :
| Méthode | Objectif |
|---|---|
setLights() | Mise à jour de l'état des feux de signalisation à partir de la recette de l'arbre des tâches |
lightsChanged() | Notifie l'interface utilisateur lorsque l'état des feux change |
smash()/ repair() | Gère la simulation de panne et les actions de récupération |
Lorsque les utilisateurs interagissent avec l'interface utilisateur :
- Un clic sur pause déclenche
smash(), simulant une panne. - Un clic sur play déclenche
repair(), rétablissant le fonctionnement normal.
Mise en œuvre de la machine à états
La logique de la machine à états est mise en œuvre par le biais d'une recette TaskTree. La méthode recipe() crée cette logique en utilisant une référence à GlueInterface:
ExecutableItem recipe(GlueInterface &iface) { return Forever { Group { // "working" state stopOnSuccess, parallel, signalAwaiterTask(&iface, &GlueInterface::smashed), // transitions to the "broken" state Forever { switchLightsTask(&iface, Light::Red, 3s), // "red" state switchLightsTask(&iface, Light::Red | Light::Yellow, 1s), // "redGoingGreen" state switchLightsTask(&iface, Light::Green, 3s), // "green" state switchLightsTask(&iface, Light::Yellow, 1s), // "greenGoingRed" state } }, Group { // "broken" state stopOnSuccess, parallel, signalAwaiterTask(&iface, &GlueInterface::repaired), // transitions to the "working" state Forever { switchLightsTask(&iface, Light::Yellow, 1s), // "blinking" state switchLightsTask(&iface, Light::Off, 1s), // "unblinking" state } } }; }
Gestion de l'état racine
L'élément de niveau supérieur Forever exécute ses enfants dans une boucle infinie. Il contient deux sous-groupes représentant les états de fonctionnement et de rupture.
Règles de transition des états :
- Les états s'exécutent en séquence, car par défaut execution mode est sequential.
- Lorsqu'un état est terminé, l'autre commence.
- Les transitions sont déclenchées lorsqu'un utilisateur clique sur le bouton "pause" ou "lecture" de l'interface utilisateur, émettant ainsi le signal correspondant.
L'état de fonctionnement "opérationnel
L'état de fonctionnement Group se compose de deux tâches exécutées dans parallel:
- La tâche signalAwaiterTask se connecte au signal
GlueInterface::smashed. Si le signal est déclenché, la tâche se termine immédiatement avec DoneResult::Success. Cela entraîne l'arrêt de l'exécution de la tâche Group et le passage de la recette à l'état "broken". - La tâche imbriquée Forever se compose de quatre tâches
switchLightsTask("red", "redGoingGreen", "green" et "greenGoingRed") exécutées sequentially dans une boucle infinie.
L'élément stopOnSuccess de chaque groupe lui indique d'arrêter son exécution lorsque l'une de ses tâches enfantines se termine par DoneResult::Success.
L'implémentation de switchLightsTask:
- met à jour les états lumineux via
GlueInterface::setLights(). - Crée un délai temporel à l'aide de timeoutTask.
- Maintient l'état pour la durée spécifiée
timeout.
static Group switchLightsTask(GlueInterface *iface, Lights lights, const milliseconds &timeout) { return { onGroupSetup([iface, lights] { iface->setLights(lights); }), timeoutTask(timeout, DoneResult::Success) }; }
L'état de fonctionnement "cassé
L'état "broken" Group est similaire à l'état " working" Group. La seule différence est qu'il se connecte au signal GlueInterface::repaired, et que les lumières passent seulement d'un état à l'autre pour allumer et éteindre la lumière jaune.
Configuration de l'application
La configuration de l'application principale crée et connecte tous les composants :
int main(int argc, char **argv) { QApplication app(argc, argv); GlueInterface iface; QTaskTree taskTree({recipe(iface)}); TrafficLight widget(iface); widget.show(); taskTree.start(); return app.exec(); }
La fonction main() instancie les objets QApplication, GlueInterface, QTaskTree et TrafficLight.
Pour construire l'objet taskTree, nous passons un recipe() construit avec l'objet iface. La fonction widget utilise également l'objet iface transmis.
Avant d'exécuter l'application, la fonction main() affiche le widget TrafficLight et démarre l'arbre des tâches.
Exécution de l'exemple
Pour exécuter l'exemple à partir de Qt CreatorOuvrez le mode Welcome et sélectionnez l'exemple à partir de Examples. Pour plus d'informations, voir Qt Creator: Tutoriel : Construire et exécuter.
© 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.