En esta página

SCXML Semáforo (Dinámico, Widgets)

Una aplicación basada en widgets que utiliza una máquina de estados cargada dinámicamente para implementar un semáforo.

Semáforo con luz verde encendida

Traffic Light demuestra cómo conectarse a las propiedades activas de un estado en una máquina de estados cargada dinámicamente.

La interfaz de usuario se crea utilizando Qt Widgets.

Ejecución del ejemplo

Para ejecutar el ejemplo desde Qt Creator, abra el modo Welcome y seleccione el ejemplo de Examples. Para más información, ver Qt Creator: Tutorial: Construir y ejecutar.

Carga dinámica de la máquina de estados

Enlazamos con el módulo Qt SCXML añadiendo las siguientes líneas a los archivos de compilación del ejemplo.

A .pro cuando se utiliza qmake:

QT += widgets scxml

A CMakeLists.txt cuando se utiliza cmake:

find_package(Qt6 REQUIRED COMPONENTS Core Gui Scxml Widgets)

target_link_libraries(trafficlight-widgets-dynamic PRIVATE
    Qt6::Core
    Qt6::Gui
    Qt6::Scxml
    Qt6::Widgets
)

Creamos dinámicamente la máquina de estados en trafficlight-widgets-dynamic.cpp:

#include "../trafficlight-common/trafficlight.h"

#include <QtWidgets/qapplication.h>
#include <QtCore/qiodevice.h>
#include <QtCore/qtextstream.h>

using namespace Qt::Literals::StringLiterals;

int main(int argc, char **argv)
{
    QApplication app(argc, argv);

    QScxmlStateMachine *machine = QScxmlStateMachine::fromFile(u":statemachine.scxml"_s);

    if (!machine->parseErrors().isEmpty()) {
        QTextStream errs(stderr, QIODevice::WriteOnly);
        const auto errors = machine->parseErrors();
        for (const QScxmlError &error : errors) {
            errs << error.toString();
        }
        return -1;
    }

Y luego la instanciamos:

    TrafficLight widget(machine);
    widget.show();
    machine->setParent(&widget);
    machine->start();

    return app.exec();
}

Conectando a los Estados

En el archivo SCXML, especificamos los estados para cada semáforo: rojo, amarillo y verde. En el elemento <onentry>, especificamos el evento a enviar al entrar en el estado y el retardo en segundos antes de enviar el evento. En el elemento <transition>, especificamos el evento que desencadena la transición al estado especificado por el atributo target:

        <state id="red">
            <onentry>
                <send event="startGoingGreen" delay="3s"/>
            </onentry>
            <transition event="startGoingGreen" target="redGoingGreen"/>
        </state>

        <state id="yellow" initial="greenGoingRed">
            <state id="redGoingGreen">
                <onentry>
                    <send event="goGreen" delay="1s"/>
                </onentry>
                <transition event="goGreen" target="green"/>
            </state>

            <state id="greenGoingRed">
                <onentry>
                    <send event="goRed" delay="1s"/>
                </onentry>
                <transition event="goRed" target="red"/>
            </state>
        </state>

        <state id="green">
            <onentry>
                <send event="startGoingRed" delay="3s"/>
            </onentry>
            <transition event="startGoingRed" target="greenGoingRed"/>
        </state>

Nos conectamos a los estados de la siguiente manera:

    machine->connectToState(u"red"_s, widget->redLight(), &LightWidget::switchLight);
    machine->connectToState(u"redGoingGreen"_s, widget->redLight(), &LightWidget::switchLight);
    machine->connectToState(u"yellow"_s, widget->yellowLight(), &LightWidget::switchLight);
    machine->connectToState(u"blinking"_s, widget->yellowLight(), &LightWidget::switchLight);
    machine->connectToState(u"green"_s, widget->greenLight(), &LightWidget::switchLight);

Proyecto de ejemplo @ code.qt.io

© 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.