实例化状态机
动态创建的和编译的状态机行为相同,具有相同的属性、状态、数据模型等。它们唯一的差异在于它们创建的方式。要从 SCXML 文件在 C++ 中动态创建一个,可以使用
auto *stateMachine = QScxmlStateMachine::fromFile("MyStatemachine.scxml");
或者,在 QML 中
import QtScxml Item { property StateMachine stateMachine: scxmlLoader.stateMachine StateMachineLoader { id: scxmlLoader source: "statemachine.scxml" } }
编译状态机可以像任何 C++ 对象一样实例化
auto *stateMachine = new MyStatemachine;
或者
MyStatemachine stateMachine;
要在 QML 中使用编译状态机,可以将它注册为一个 QML 类型
struct MyStateMachineRegistration { Q_GADGET QML_NAMED_ELEMENT(MyStateMachine) QML_FOREIGN(MyStateMachine) QML_ADDED_IN_VERSION(1, 0) };
然后您可以在 QML 中实例化它,如下所示
import MyStateMachine 1.0 MyStateMachine { id: stateMachine }
要编译状态机,必须在项目构建文件中添加以下行
当使用 cmake 时
find_package(Qt6 REQUIRED COMPONENTS Scxml)
target_link_libraries(mytarget PRIVATE Qt6::Scxml)
qt6_add_statecharts(mytarget
MyStatemachine.scxml
)
当使用 qmake 时
QT += scxml
STATECHARTS = MyStatemachine.scxml
这将告诉 qmake 运行 qscxmlc,它生成 MyStatemachine.h 和 MyStatemachine.cpp,并将它们添加到项目的头文件和源文件中。默认情况下,生成的文件保存在构建目录中。可以设置 qmake 的 QSCXMLC_DIR 或 cmake 的 OUTPUT_DIRECTORY 变量来指定另一个目录。可以设置 qmake 的 QSCXMLC_NAMESPACE 或 cmake 的 NAMESPACE 变量,以将状态机代码放入 C++ 命名空间。
实例化状态机后,可以连接到任何状态的活动属性,如下所示。例如,如果交通灯的状态机有一个表示灯是红色的状态(在 scxml 文件中具有便利的 id "red"),可以编写
stateMachine->connectToState("red", [](bool active) { qDebug() << (active ? "entered" : "exited") << "the red state"; });
并且在 QML 中
Light { id: greenLight color: "green" visible: stateMachine.green }
如果要在状态机发送事件时接收通知,可以连接到相应的信号。例如,对于通过发送事件表示播放停止的媒体播放器状态机,可以编写
stateMachine->connectToEvent("playbackStopped", [](const QScxmlEvent &){ qDebug() << "Stopped!"; });
并且在 QML 中
import QtScxml EventConnection { stateMachine: stateMachine events: ["playbackStopped"] onOccurred: console.log("Stopped!") }
向状态机发送事件同样简单
stateMachine->submitEvent("tap", QVariantMap({ { "artist", "Fatboy Slim" }, { "title", "The Rockafeller Skank" } }));
这将在状态机内部生成一个具有 _event.data 中可用内容的 "tap" 事件。在 QML 中
stateMachine.submitEvent("tap", { "artist": "Fatboy Slim" "title": "The Rockafeller Skank" })
注意:状态机需要一个 QEventLoop
才能正确工作。事件循环用于实现事件的 delay
属性,并在从嵌套(或父)状态机接收到事件时安排状态机的处理。QML 应用程序或小部件应用程序始终有一个运行的事件循环,所以不需要额外的东西。对于其他应用程序,必须调用 QApplication::run
来启动事件循环处理。
© 2024 The Qt Company Ltd. 本文档收录的贡献版权属于其各自的所有者。本提供的文档是在 Free Software Foundation 发布的 GNU 自由文档许可协议版本 1.3 的条款下许可的。Qt 和相应的标志是 The Qt Company Ltd. 在芬兰和/或其他国家的商标。所有其他商标均为其各自所有者的财产。