Qt5.8如何在子状态机上使用SCXML框架?
我正在尝试构建一个系统,该系统由一个主状态机编排,并且对于它正在执行的任务具有不同的子状态机。作为一名长期使用Qt的用户,我在Qt5.8中查看了新的SCXML实现。但是,我不知道如何使用5.8提供的API正确地实现子状态机 我的想法是使用主状态机,然后在主状态机的状态中调用特定的子状态机。在调用子状态机时,我不知道如何在顶级状态机对象发出Qt5.8如何在子状态机上使用SCXML框架?,qt,scxml,Qt,Scxml,我正在尝试构建一个系统,该系统由一个主状态机编排,并且对于它正在执行的任务具有不同的子状态机。作为一名长期使用Qt的用户,我在Qt5.8中查看了新的SCXML实现。但是,我不知道如何使用5.8提供的API正确地实现子状态机 我的想法是使用主状态机,然后在主状态机的状态中调用特定的子状态机。在调用子状态机时,我不知道如何在顶级状态机对象发出invokedServicesChanged(..)后访问它们,我可以访问指向QScxmlInvokableService的指针,但不能访问相关的状态机 此外,
invokedServicesChanged(..)
后访问它们,我可以访问指向QScxmlInvokableService
的指针,但不能访问相关的状态机
此外,顶级状态机对象仅公开来自顶层的状态和事件,而不公开来自调用的状态机的状态和事件。例如,topLevelStateMachine->activeStateNames()
只列出了顶级状态
查看Qt的源代码,我发现
qscxmlnvokableService
实际上是qscxmlservice
的基类,其中包含指向相关状态机的指针。不幸的是,qscxmlservice
是在qscxmlnvokableService\u p.h
中定义的,它是私有的,正如名称中的\u p
所示。那么,我应该如何使用公共SCXMLAPI呢?我错过什么了吗?IIRC SCXML支持是5.7中的一个技术预览,但现在作为正态分布的一部分包含在5.8中。我花了大约一周的时间研究这些示例,然后编写自己的状态机和响应它的代码。这花了一段时间,因为文档并不像可能的那样清晰
我发现它确实检索状态机中包含的所有状态,包括子状态
我花了好几次时间才弄明白这一点。关键是子状态机包含在特定状态中。(状态机的图形视图在此提供帮助。)
在本例中,总体顶级机器中只有两种状态:工作状态
和中断状态
。转换由事件smash
和repair
控制
在这两个状态中的每一个都有较小的状态机。Breaked包含两种状态的状态机:闪烁
和取消链接
。当输入中断
时,该状态机在状态闪烁
下启动
当处于中断
的子状态闪烁
时,如果使用假
(默认)调用,activeStateNames将返回闪烁
,或者使用真
调用时返回闪烁
那你怎么用这个呢
如果我想根据特定状态设置/取消设置某些内容,我可以在机器中connectToState
。当状态在active和inactive之间变化时,我连接到的插槽将被调用,它将收到一个布尔值,表示状态是否为active。在交通灯示例中,状态红色
连接到红灯
。由于红灯
应在处于红灯
状态时亮起,否则不亮,因此它连接到插槽时采用布尔值:true
亮起灯,false
关闭灯
好吧,但如果我想在进入状态时捕捉事件呢
我只需选择状态,然后添加onEntry->send并指定事件名称。这将导致在我进入状态时发送事件。可以使用
connectToEvent
将此事件路由到插槽(在Qt 5.8中)。[Qt 5.7版本只有一个通用的eventoccurrent
信号,您可以将该信号发送到插槽,然后使用event.name()查询哪个事件。]我认为这是API中的一个疏忽。您可以随意将QT+=scxml\u private
添加到项目中,并使用实现细节来完成您需要完成的工作。Qt模块是一个非常新的模块,是的,它缺少一些必要的位来让它变得有用。当你说“子状态机”时,你是指单独的.scxml
状态机,还是指状态机?如果是前者,为什么不是后者?独立的状态机。我不认为在一个XML文件中拥有一个大型状态机是一个好主意,但从理论上讲,它也可以用复合状态来解决。如何使用SCXML和Qt组织一个包含许多子状态的大型状态图?我不知道一般如何回答这个问题。我在过去做过几个“大型”(取决于你的定义)状态图。每一个都是不同的,对于如何组织各州有不同的方法,当然,对于如何以平行和复合的方式组织各州,我必须做出设计决策,每一个都有不同的利弊。一个好的可视化编辑器对此很重要:请参见中的图2以获取一个摘录的示例。Thx以获取我需要研究的快速答案:)