Feu tricolore
L'exemple Traffic Light montre comment utiliser Qt State Machine Overview pour mettre en œuvre le flux de contrôle d'un feu de circulation.

Dans cet exemple, nous écrivons une classe TrafficLightWidget. Le feu de signalisation comporte trois feux : Rouge, jaune et vert. Le feu passe d'un feu à l'autre (rouge à jaune à vert à jaune à nouveau à rouge) à certains intervalles.
class LightWidget : public QWidget { Q_OBJECT Q_PROPERTY(bool on READ isOn WRITE setOn) public: explicit LightWidget(const QColor &color, QWidget *parent = nullptr) : QWidget(parent), m_color(color) { } bool isOn() const { return m_on; } void setOn(bool on) { if (on == m_on) return; m_on = on; update(); } public slots: void turnOff() { setOn(false); } void turnOn() { setOn(true); } protected: void paintEvent(QPaintEvent *) override { if (!m_on) return; QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing); painter.setBrush(m_color); painter.drawEllipse(rect()); } private: QColor m_color; bool m_on = false; };
La classe LightWidget représente un seul feu de signalisation. Elle fournit une propriété on et deux slots, turnOn() et turnOff(), pour allumer et éteindre le feu, respectivement. Le widget se peint dans la couleur qui est passée au constructeur.
class TrafficLightWidget : public QWidget { Q_OBJECT public: explicit TrafficLightWidget(QWidget *parent = nullptr) : QWidget(parent) { auto vbox = new QVBoxLayout(this); m_red = new LightWidget(Qt::red); vbox->addWidget(m_red); m_yellow = new LightWidget(Qt::yellow); vbox->addWidget(m_yellow); m_green = new LightWidget(Qt::green); vbox->addWidget(m_green); auto pal = palette(); pal.setColor(QPalette::Window, Qt::black); setPalette(pal); setAutoFillBackground(true); } LightWidget *redLight() const { return m_red; } LightWidget *yellowLight() const { return m_yellow; } LightWidget *greenLight() const { return m_green; } private: LightWidget *m_red; LightWidget *m_yellow; LightWidget *m_green; };
La classe TrafficLightWidget représente la partie visuelle du feu de circulation ; il s'agit d'un widget qui contient trois feux disposés verticalement et qui fournit des fonctions d'accès à ces feux.
QState *createLightState(LightWidget *light, int duration, QState *parent = nullptr) { auto lightState = new QState(parent); auto timer = new QTimer(lightState); timer->setInterval(duration); timer->setSingleShot(true); auto timing = new QState(lightState); QObject::connect(timing, &QAbstractState::entered, light, &LightWidget::turnOn); QObject::connect(timing, &QAbstractState::entered, timer, QOverload<>::of(&QTimer::start)); QObject::connect(timing, &QAbstractState::exited, light, &LightWidget::turnOff); auto done = new QFinalState(lightState); timing->addTransition(timer, &QTimer::timeout, done); lightState->setInitialState(timing); return lightState; }
La fonction createLightState() crée un état qui allume un feu lorsque l'on entre dans cet état et l'éteint lorsque l'on en sort. L'état utilise un minuteur et, comme nous le verrons, le délai d'attente est utilisé pour passer d'un état lumineux à un autre. Voici le diagramme d'état de l'état lumineux :

class TrafficLight : public QWidget { Q_OBJECT public: explicit TrafficLight(QWidget *parent = nullptr) : QWidget(parent) { auto vbox = new QVBoxLayout(this); auto widget = new TrafficLightWidget; vbox->addWidget(widget); vbox->setContentsMargins(QMargins()); auto machine = new QStateMachine(this); auto redGoingYellow = createLightState(widget->redLight(), 3000); redGoingYellow->setObjectName("redGoingYellow"); auto yellowGoingGreen = createLightState(widget->yellowLight(), 1000); yellowGoingGreen->setObjectName("yellowGoingGreen"); redGoingYellow->addTransition(redGoingYellow, &QState::finished, yellowGoingGreen); auto greenGoingYellow = createLightState(widget->greenLight(), 3000); greenGoingYellow->setObjectName("greenGoingYellow"); yellowGoingGreen->addTransition(yellowGoingGreen, &QState::finished, greenGoingYellow); auto yellowGoingRed = createLightState(widget->yellowLight(), 1000); yellowGoingRed->setObjectName("yellowGoingRed"); greenGoingYellow->addTransition(greenGoingYellow, &QState::finished, yellowGoingRed); yellowGoingRed->addTransition(yellowGoingRed, &QState::finished, redGoingYellow); machine->addState(redGoingYellow); machine->addState(yellowGoingGreen); machine->addState(greenGoingYellow); machine->addState(yellowGoingRed); machine->setInitialState(redGoingYellow); machine->start(); } };
La classe TrafficLight combine le TrafficLightWidget avec une machine à états. Le graphe d'état comporte quatre états : rouge-jaune, jaune-vert, vert-jaune et jaune-rouge. L'état initial est rouge-jaune ; lorsque le temporisateur de l'état est épuisé, la machine à états passe à l'état jaune-vert. Le même processus se répète pour les autres états. Voici à quoi ressemble le diagramme d'état :

int main(int argc, char **argv) { QApplication app(argc, argv); TrafficLight widget; widget.resize(110, 300); widget.show(); return app.exec(); }
La fonction main() construit un feu de circulation et l'affiche.
© 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.