news 2026/4/23 11:42:55

使用Qt Creator创建和编辑状态图详细教程

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
使用Qt Creator创建和编辑状态图详细教程

使用Qt Creator创建和编辑状态图详细教程

  • 一、使用Qt Creator创建和编辑状态图
    • 1、创建新项目
    • 2、新建scxml文件
    • 3、编辑状态图实现下面这个状态
  • 二、如何使用状态图
  • 三、Qt SCXML 模块详解
    • 1、SCXML 概述
    • 2、Qt SCXML 模块的作用
    • 3、使用 Qt SCXML 模块的基本步骤
      • 3.1 编写 SCXML 文件
      • 3.2 (可选但推荐) 使用 `qscxmlc` 编译 SCXML 文件
      • 3.3 在 Qt 项目中集成
    • 1、关键特性与优势
    • 5、示例:编译后状态机的使用 (C++)
    • 6、总结

一、使用Qt Creator创建和编辑状态图

1、创建新项目



2、新建scxml文件



3、编辑状态图实现下面这个状态

<scxmlxmlns="http://www.w3.org/2005/07/scxml"version="1.0"initial="MainControl"><!-- 主控制状态 --><stateid="MainControl"><initial><transitiontarget="Stopped"/></initial><!-- 设备停止状态 --><stateid="Stopped"><onentry><logexpr="'设备已停止'"/></onentry><transitionevent="start"target="Running"/></state><!-- 设备运行状态 --><stateid="Running"initial="Preparing"><onentry><logexpr="'设备启动中...'"/></onentry><!-- 准备阶段 --><stateid="Preparing"><transitionevent="ready"target="Working"/></state><!-- 工作阶段 --><stateid="Working"><transitionevent="emergency.stop"target="Stopped"/><transitionevent="pause"target="Paused"/></state><!-- 暂停状态 --><stateid="Paused"><transitionevent="resume"target="Working"/><transitionevent="emergency.stop"target="Stopped"/></state></state></state><!-- 并行电池监控状态 --><parallelid="BatteryMonitor"><stateid="Normal"><transitioncond="BatteryLevel&lt;20"target="LowBattery"/></state><stateid="LowBattery"><onentry><logexpr="'警告:电量不足!'"/></onentry><transitioncond="BatteryLevel&gt;= 20"target="Normal"/></state></parallel><!-- 全局事件处理 --><transitionevent="system.shutdown"target="Shutdown"/><finalid="Shutdown"><onentry><logexpr="'系统关闭'"/></onentry></final></scxml>


单击状态会出现箭头

绘制完成

查看结果:

<?xml version="1.0" encoding="UTF-8"?><scxmlxmlns="http://www.w3.org/2005/07/scxml"version="1.0"binding="early"xmlns:qt="http://www.qt.io/2015/02/scxml-ext"name="MainControl"qt:editorversion="18.0.0"initial="Stopped"><qt:editorinfoinitialGeometry="221.80;107.85;-20;-20;40;40"/><stateid="Stopped"><qt:editorinfoscenegeometry="535.18;129.21;475.18;79.21;120;100"geometry="535.18;129.21;-60;-50;120;100"/><transitiontype="external"event="start"target="Running"/></state><stateid="Running"><qt:editorinfoscenegeometry="419.70;326.60;-174.47;359.95;1419.29;255.59"geometry="419.70;326.60;-594.16;33.35;1419.29;255.59"/><stateid="Preparing"><qt:editorinfoscenegeometry="383.59;291.38;323.59;241.38;120;100"geometry="-490.41;161.15;-60;-50;120;100"/><transitiontype="external"event="ready"target="Working"/></state><stateid="Working"><qt:editorinfoscenegeometry="471.49;487.75;411.49;437.75;120;100"geometry="51.79;161.15;-60;-50;120;100"/><transitiontype="external"event="pause"target="Paused"/></state><stateid="Paused"><qt:editorinfoscenegeometry="1616.74;291.38;1556.74;241.38;120;100"geometry="742.74;161.15;-60;-50;120;100"/><transitiontype="external"event="resume"target="Working"/></state></state></scxml>

其余自己添加

二、如何使用状态图

参考我这篇文档:Qt SCXML 模块详解

三、Qt SCXML 模块详解

1、SCXML 概述

SCXML (State Chart XML) 是一种基于 XML 的 W3C 标准,用于描述复杂的状态机(State Machines)。它提供了一种形式化的方式来定义:

  • 状态(States):如初始状态最终状态复合状态(包含子状态)、并行状态
  • 转换(Transitions):状态之间的迁移路径,由事件触发,并可带有条件执行的动作
  • 事件(Events):触发状态转换的信号。
  • 动作(Actions):在进入/退出状态或执行转换时执行的逻辑,如发送事件、调用脚本、操作数据模型等。
  • 数据模型(Data Model):用于存储状态机上下文相关的数据。

2、Qt SCXML 模块的作用

Qt 的 SCXML 模块 (QtSCXML) 提供了在 Qt 应用程序中使用 SCXML 标准的能力。其主要组件包括:

  • QScxmlStateMachine:核心类,代表一个 SCXML 状态机实例。它:
    • 解析 SCXML 文件或字符串。
    • 管理状态机的生命周期(初始化、启动、停止)。
    • 提供接口与状态机交互:发送事件、查询当前状态、订阅状态变化通知等。
    • 可以与 Qt 的信号/槽机制集成。
  • SCXML 编译器 (qscxmlc):一个命令行工具(或可通过 CMake/QMake 集成),用于将 SCXML 文件编译成 C++ 代码(.h.cpp文件)。
    • 目的:提升运行时性能(避免 XML 解析开销)和类型安全性(生成的类提供事件类型和属性访问器)。
    • 生成内容:一个继承自QScxmlStateMachine的特定状态机类。该类:
      • 提供强类型的事件发送方法(如submitEventName()代替通用的submitEvent("EventName"))。
      • 提供访问 SCXML 数据模型中定义的数据属性的方法(如property()或生成的 getter/setter)。
      • 为每个状态定义了枚举常量(便于查询当前状态)。
  • Qt 状态机集成:虽然 SCXML 本身功能强大,但QScxmlStateMachine可以无缝地与 Qt 的事件循环和对象系统协作。

3、使用 Qt SCXML 模块的基本步骤

3.1 编写 SCXML 文件

使用文本编辑器或专门的 SCXML 编辑器(如qscxml提供的qscxmlmon)创建描述状态机的.scxml文件。例如,一个简单的开关状态机:

<scxmlxmlns="http://www.w3.org/2005/07/scxml"version="1.0"initial="off"><stateid="off"><transitionevent="switch"target="on"/></state><stateid="on"><transitionevent="switch"target="off"/></state></scxml>

3.2 (可选但推荐) 使用qscxmlc编译 SCXML 文件

  • 命令行
    qscxmlc -o LightSwitchMachine.h LightSwitchMachine.scxml
  • CMake
    find_package(Qt6 COMPONENTS SCXML REQUIRED) qt_add_scxml_file(LightSwitchMachine "LightSwitchMachine.scxml" OUTPUT_HEADER LightSwitchMachine.h OUTPUT_SOURCE LightSwitchMachine.cpp)
  • qmake
    scxml_files = LightSwitchMachine.scxml qscxmlc.commands = qscxmlc -o ${QMAKE_FILE_OUT} ${QMAKE_FILE_IN} QMAKE_EXTRA_COMPILERS += scxmlc

3.3 在 Qt 项目中集成

  1. 配置项目:确保项目文件(.pro,CMakeLists.txt)包含scxml模块。
    • qmake:QT += scxml
    • CMake:find_package(Qt6 COMPONENTS SCXML REQUIRED)target_link_libraries(myapp Qt6::SCXML)
  2. 包含头文件:如果使用了qscxmlc,包含生成的头文件#include "LightSwitchMachine.h";否则使用#include <QtScxml/QScxmlStateMachine>
  3. 创建状态机实例
    • 未编译
      QScxmlStateMachine*machine=QScxmlStateMachine::fromFile(":/LightSwitchMachine.scxml");
    • 已编译
      LightSwitchMachine*machine=newLightSwitchMachine();
  4. 启动状态机
    machine->start();
  5. 与状态机交互
    • 发送事件
      // 未编译 (通用方法)machine->submitEvent("switch");// 已编译 (类型安全方法)machine->submitSwitch();// 假设事件名为 'switch'
    • 查询状态
      QString currentState=machine->activeStateNames().first();// 获取根状态下的活动状态名// 已编译 (使用枚举)if(machine->isActive(LightSwitchMachine::On)){...}
    • 连接信号
      // 状态进入/退出信号connect(machine,&QScxmlStateMachine::reachedStableState,this,&MyClass::onStableState);connect(machine,&QScxmlStateMachine::stateEntered,this,&MyClass::onStateEntered);connect(machine,&QScxmlStateMachine::stateExited,this,&MyClass::onStateExited);// 已编译状态机可能有更具体的信号

1、关键特性与优势

  • 可视化与形式化:SCXML 文件可以可视化编辑,状态机行为清晰定义。
  • 复用性:状态机定义(SCXML 文件)独立于业务逻辑代码。
  • 可维护性:复杂状态逻辑集中管理,易于修改。
  • 性能:编译后的状态机运行高效。
  • 集成:与 Qt 的信号/槽、事件循环完美结合。
  • 复杂状态支持:支持嵌套状态、并行状态、历史状态等。

5、示例:编译后状态机的使用 (C++)

#include"LightSwitchMachine.h"// 由 qscxmlc 生成#include<QCoreApplication>#include<QDebug>intmain(intargc,char*argv[]){QCoreApplicationapp(argc,argv);LightSwitchMachine machine;machine.start();// 启动状态机,初始状态为 "off"// 连接信号查看状态变化QObject::connect(&machine,&LightSwitchMachine::onEntered,[](constQString&state){qDebug()<<"Entered state:"<<state;});// 发送事件切换状态machine.submitSwitch();// 从 off -> onmachine.submitSwitch();// 从 on -> offreturnapp.exec();}

6、总结

Qt 的 SCXML 模块为在 Qt 应用程序中实现基于标准的、复杂的、可维护的状态机行为提供了强大的支持。通过编写 SCXML 文件定义状态逻辑,利用QScxmlStateMachine运行,并可选地使用qscxmlc编译器提升性能和类型安全,开发者能够高效地管理应用的状态流转。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/23 11:19:27

国家级专精特新“小巨人”第一至七批名单(1.94万家)

专精特新企业是指具有专业化、精细化、特色化、新颖化特征的中小企业&#xff0c;而“小巨人”在特定细分市场中占据领先地位&#xff0c;并且具有较强自主创新能力和发展潜力&#xff1b;在我国&#xff0c;专精特新“小巨人”企业专注于产业链上的某个环节或某类产品&#xf…

作者头像 李华
网站建设 2026/4/23 11:20:23

Qwen3-14B本地部署指南:高效私有化大模型实战

Qwen3-14B本地部署实战&#xff1a;打造企业级私有化AI引擎 在金融合规部门的深夜会议室里&#xff0c;法务团队正为一份跨国并购合同焦头烂额——328页的PDF文档中藏着十几个关键风险点&#xff0c;而距离截止时间只剩6小时。与此同时&#xff0c;某电商平台的客服系统正承受着…

作者头像 李华
网站建设 2026/4/23 11:18:47

用美食来理解JavaScript面向对象编程

欢迎使用我的小程序&#x1f447;&#x1f447;&#x1f447;&#x1f447; 俱好用助手功能介绍 大家好&#xff01;今天我们要聊一个听起来有点“高大上”的话题——JavaScript面向对象编程&#xff08;OOP&#xff09;。别担心&#xff0c;我不会用一堆专业术语砸晕你&#…

作者头像 李华
网站建设 2026/4/23 11:19:06

让代码学会“等外卖”:JavaScript异步编程趣谈

欢迎使用我的小程序&#x1f447;&#x1f447;&#x1f447;&#x1f447; 俱好用助手功能介绍 大家好&#xff01;今天我们来聊聊JavaScript中一个既重要又有趣的话题——异步编程。如果你曾经遇到过网页“卡死”的情况&#xff0c;或者好奇为什么有些操作不会阻塞页面交互&…

作者头像 李华
网站建设 2026/4/23 11:32:02

GDDR6 VS GDDR6X:GPU与AI芯片的高性能显存技术的选择

深入了解 GDDR6 与 GDDR6X 显存的关键差异&#xff1a;对比带宽、能效、信号传输方式以及面向先进 GPU 架构的设计权衡。 引言 随着现代 GPU 对高速度与高能效的需求日益增长&#xff0c;GDDR6 与 GDDR6X 之间的选择已变得至关重要。这两种显存标准共同支撑着下一代游戏、可视…

作者头像 李华
网站建设 2026/4/23 9:53:57

常见网络连通性测试指令

常见网络连通性测试指令 ping &#xff1a;仅用来测试到ip的连通性&#xff0c;ping基于ICMP 协议&#xff08;Internet 控制报文协议&#xff09;&#xff0c;它的作用是向目标主机发送ICMP Echo Request包&#xff0c;等待对方返回ICMP Echo Reply包&#xff0c;以此判断 “主…

作者头像 李华