状态图提供了一种图形化的方式来模拟系统对刺激的反应。这是通过定义系统可能处于的状态,以及系统如何从一个状态转移到另一个状态(状态之间的转换)来实现的。事件驱动系统(如Qt应用程序)的一个关键特征是,行为通常不仅取决于上一个或当前事件,还取决于它之前的事件。使用状态图,此信息很容易表达。
Qt Creator提供了一个用于将带有样板代码的状态图XML(SCXML)文件添加到项目的项目向导,以及一个用于编辑状态图的实验性SCXML编辑器。您可以使用SCXML编辑器向文件添加状态和转换。然后,您可以使用Qt SCXML模块中的类将从Qt应用程序中的文件创建的状态机嵌入到Qt应用程序中。
您可以将状态从Common State视图(1)拖放到状态编辑器(2)。在状态编辑器中选择一个状态,然后使用工具按钮(3)创建转换(4)及其目标状态。
您可以在结构视图(5)中查看状态图结构,并在属性视图(6)中指定所选状态或转换的属性。
您可以使用工具栏按钮(7)执行编辑、缩放、放大、导航和平移状态图表等功能,以及截屏和查看统计数据。
要在状态编辑器中放大和缩小整个状态图表,请选择放大或缩小,或按Ctrl键并使用鼠标滚轮。要使整个状态图一次在状态编辑器中可见,请选择(布满视图)。
要在状态编辑器中查看大型状态图表的特定部分,请选择(导航器)并移动要查看的部件上的导航框。
要使用放大镜放大状态图表的一部分,请选择(放大镜工具)。要更快地移动放大镜工具,请按下Alt键。
要平移状态图表,请选择(平移)。要加快平移的速度,请按下Shift键。
要在状态图中查看有关状态数和转换数的统计信息,请选择(查看统计信息)。
要从状态图表中搜索,请使用搜索窗格。搜索将检查整个SCXML树,以查找与搜索条件匹配的属性。
要将状态图的当前可见部分另存为图像,请选择(保存屏幕快照)。要将整个状态图表另存为图像,请选择(将画布导出到图像)。
选择文件>;新建文件或项目>;文件和类>;建模>;状态图表>;选择创建空状态图表并在SCXML编辑器中将其打开。
将子状态拖放到初始状态以创建复合状态,或使用工具按钮创建从选定状态及其目标状态的过渡。
例如,要引发或发送事件,请使用上下文菜单命令将可执行内容添加到状态或转换的<;onentry>;和<;onexit>;元素。
当状态机响应于事件而进入状态时,其进入的状态变为活动状态。
状态图是分层的,因此状态可以嵌套在其他状态中,以创建复合状态。
并行状态包含并行执行且全部同时处于活动状态的子状态。事件由每个子状态独立处理,并且可能会为每个子状态触发不同的转换。
最终状态使状态机能够完成。当状态机进入顶层最终状态时,它发出完成信号并停止。您可以在复合状态中创建最终状态,以隐藏复合状态的内部详细信息。外界只能进入状态,并在状态结束时收到通知。当并行状态的所有子状态都达到最终状态时,该并行状态结束。
历史记录状态是一个伪状态,它表示父状态上次退出父状态时所在的子状态。将历史记录状态创建为要记录其当前子状态的状态的子级。当状态机在运行时检测到存在这样的状态时,它会在父状态退出时自动记录当前(真实)子状态。到历史状态的转换实际上是到状态机先前保存的子状态的转换。状态机自动将转换转发到真实子状态。
在状态编辑器中选择一个状态,然后选择状态工具按钮以创建转换及其目标状态。
在SCXML编辑器内或在SCXML编辑器和编辑模式之间复制和粘贴状态。
您可以将状态拖动到其他状态之上以创建复合状态,也可以将子状态拖出其父状态。要在其父状态内移动子状态,请在移动它们的同时按住Ctrl键。
您可以使用工具栏按钮在状态编辑器中对齐状态、调整其大小以及更改默认配色方案。重叠的状态用红色标记。
要在结构视图中展开或折叠状态树结构,请双击某个状态。
要在状态编辑器中更详细地查看嵌套状态的子状态,请选择缩放到状态。
要确保状态ID在复合状态机中是唯一的,请选择(切换完整命名空间)。父状态的名称将添加到子状态的名称中,并用两个冒号(::)分隔。例如:
转换定义状态如何响应由状态机或外部实体生成的事件。当事件发生时,状态机检查在活动状态中定义的匹配转换,并移动到其目标状态。
要创建从选定状态到新状态的过渡,请在要添加目标状态的位置拖动并松开鼠标。当您绘制到另一个状态中心的过渡时,它指向该状态的中心,但您也可以绘制到该状态边缘的过渡。
要向过渡添加边缘点,请选择一条过渡线。每条线只允许有两个边缘点,不必要的边缘点会自动删除。若要删除选定的边缘点,请在关联菜单中选择“删除点”。
您可以将可执行内容添加到状态图中,以使状态机能够修改其数据模型并与外部实体交互。
使用上下文菜单命令将可执行内容添加到<;onentry>;和<;onexit>;元素或转换:
迭代集合中的项并对每个项执行操作(<;foreach>;)。
在转换期间,状态机执行您为处于离开状态的<;onexit>;元素指定的内容,然后执行转换中的内容,然后执行进入状态的<;onentry>;元素的内容。