本页内容

SCXML 交通信号灯(动态,小部件)

一个基于小部件的应用程序,它使用动态加载的状态机来实现交通信号灯。

交通信号灯亮起绿灯

“交通信号灯”演示了如何连接到动态加载的状态机中某个状态的“active”属性。

用户界面使用Qt Widgets 创建。

运行示例

您可以通过以下方式运行该示例:

动态加载状态机

通过在示例的构建文件中添加以下几行代码,将Qt SCXML 模块链接进来。

使用 qmake 时,在.pro文件中添加:

QT += widgets scxml

使用 cmake 时,在CMakeLists.txt中:

find_package(Qt6 REQUIRED COMPONENTS Core Gui Scxml Widgets)

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

我们在trafficlight-widgets-dynamic.cpp 中动态创建状态机:

#include "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;
    }

然后对其进行实例化:

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

    return app.exec();
}

连接到状态

在 SCXML 文件中,我们为每个信号灯指定了状态:红、黄和绿。在 `<onentry> ` 元素中,我们指定了进入该状态时要发送的事件,以及发送事件前的延迟时间(以秒为单位)。在 `<transition> ` 元素中,我们指定了触发向 `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>

我们按以下方式连接到这些状态:

    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);

示例项目 @ 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.