最近接触了SCXML这个状态描述文本,简单来讲就是描述了整个状态的变迁过程的一种XML格式的表格。Qt labs中有一个项目就是QScxml,它基于QStateMachine上层制作,可以直接读取SCXML格式的文件生成内部状态对象和成员,可以直接在Qt中进行状态变迁,十分方便。

先来简单介绍一下SCXML的格式,以

<scxml initial="FirstState" version="0.9" xmlns="http://www.w3.org/2005/07/scxml">

作为整个SCXML的开头,scxml标签旁的initial表示状态机启动之后进入的第一个初始化状态,在这里我写了FirstState,表示状态几一启动,就进入了FirstState.

<state id="FirstState" initial="FirstChildNode">

以state标签开头表示了状态的基本概念,其中的id是作为该状态的索引号给你之后写target进行索引,这个时候同学会看到又出现了一个initial,这时的FirstChildNode表示此时的FirstState并不是一个原子状态,而是一个组合状态的父状态。而FirstChildNode恰恰就是它的子状态。也就是说进入了FirstState之后,就会立即进入FirstChildNode,期间如果你调用了<onentry>和<onexit>标签,你会发现调用了多次,不必奇怪,其实你的状态是进入了一层一层中的最里层,每进一层就会调用<onentry>和<onexit>。

<transition event="Key.A" target="SecondState"></transition>
<transition event="Key.B" target="ThirdState"></transition>

又来新东西了,这个<transition>标签表示真正的事务处理过程,之后的event属性表示你传递给QScxml中的postNamedEvent(const QString)函数中的QString,所以我之前提过那个id的作用,就是全局的索引号,同时请注意:SCXML中默认的event是前缀查找,也就是说对于event="GameTest"来说,你输入"GameTest","Game","Game.","Game.*"效果是完全一样的,不过我试了下在QScxml中只有第一种和第三种有效(官方说明)。之后的<target>自然很好理解,就是你在这个状态下,经过了event事件,达到了target状态(target不能接收函数,必须是字符串状态变量而cond可以接收函数或者字符串)。例子中就表示无论你在FirstState中的哪个孩子中,只要你收到了Key.A事件,你都会跳出子状态乃至父状态,直接跳到对应的SecondState中去。注意:写在父状态中的translation是给它以及它的孩子全局共享的,如果你觉得你可能在孩子节点中对于某一个事件你不满意,你想要重写,那你完全可以在FirstChildNode中写下

<transition event="Key.A" target="FourhState"></transition>
<transition event="Key.B" target="FifthState"></transition>

这个时候状态机会优先处理最子层的事务处理,如果状态机发现在最子层并没有完成该事件(包括没有找到该translation和找到translation可是cond为false)都会将事件向上传递给父状态进行处理。

在来说说比较有用的标签<cond>,这个标签可以放在<translation>中也可以放在<if>中,当放在<translation中时>

<transition event="Key.A" target="FourhState" cond="isTrue"></transition>

表明当isTrue为true的时候,target才真正进行转移(在这里isTrue即可以是简单变量也可以是script函数来返回bool值),比较常用的用法有

<translation event="Key.A">
<if cond="isTrue()">
<script>FuncA()</script>
<elseif cond="isFalse()"/>
<script>FuncB()</script>
<else/>
<script>FuncC()</script>
</if>
</translation>

表明事件Key.A来的时候进行cond判断来调用相应的script。

另外我们也可以用到状态机在上而下处理事件的机制,来进行灵活的target动态转换工作.

<transition event="Key.A" target="A" cond="isTrue()" />
<transition event="Key.A" target="B" >

细心的你一定会发现,怎么两个translation的event一样。其实这种用法在W3C的examples中也提到过,因为状态机在上而下的处理机制,你可以在断言为false的时候有一个默认的target,而在true的时候进入你事先设定的target,可以非常灵活的使用这种机制进行判断.

另外介绍一下两个也比较重要的标签,在上文也提到过<onentry>和<onexit>,

<onentry>
<script>
enterState("A");
</script>
</onentry>
<onexit>
<script>
exitState("B");
</script>

表明在进入和退出该状态的时候自动触发的事件,这里默认调用的script,你可以很灵活的控制状态切换时应该需要的工作.

QScxml中有一个功能非常强大的函数

void QScxml::registerObject (QObject* o, const QString & name, bool recursive)

用它进行注册之后,你可以在SCXML的文件中写各种script function,比如你注册的时候m_scxml->registerObject(this, "Widget", true),这个时候你就可以在SCXML文件中写下

<script>
function show()
{
Widget.show();
 }
</script>

表明无论你在translation还是onentry还是onexit中的<script>标签写show()这个函数,你最终都会通过QScxml这个强大的类让你可以和它进行交互。如果你嫌写script function麻烦,

你也可以直接在<script>标签中写上

Widget.show();

一样可以直接运行。script function的强大不仅仅在于可以通过QScxml让你和你的对象进行交互,同时它也可以用来做断言cond判断,比如

function isTrue()
{
return Widget.isGood();
}

你可以非常灵活的实现你自己类的断言函数,配合之前的translation中的cond做到动态切换target,非常方便。

今天就简单介绍到这里,在开始接触SCXML的时候发现国内的资料很少,写这篇博文也当贡献自己的一份力了,更多的内容需要你自己去挖掘,希望你会喜欢这篇文章,留下你的脚印,给我支持,谢谢:)

SCXML和QScxml使用总结的更多相关文章

  1. scxml 图像展示器 (基于C++ MFC GDI tinyxpath的实现)

    以前的时候学习新东西没有总结的习惯,周末把以前研究的东西翻了翻,稍微总结下. Scxml是w3c出来的基于状态机的对话脚本语言标准,具体内容可以谷歌到,这里讲述自己开发的一个把scxml转化为可交互图 ...

  2. 【基础】Qt SCXML Calculator QML Example

    Qt SCXML Calculator QML Example 这个系统自带的例子原本主要是用来说明SCXML机制的,但是由于计算器的经典和简洁,我认为用来练习QML非常合适,原本的例子还有一些问题, ...

  3. java jar包收集

    activation~与javaMail有关的jar包,使用javaMail时应与mail.jar (mail.jar和activation.jar)一起加入到lib中去,具体负责mail的数据源和类 ...

  4. apache commons Java包简介

    更多信息,请参考:http://commons.apache.org/ 一.Commons BeanUtils说明:针对Bean的一个工具集.由于Bean往往是有一堆get和set组成,所以BeanU ...

  5. Apache Commons 简述

    Apache Commons 是一个关注于可复用的 Java 组件的 Apache 项目.Apache Commons 由三部分构成: Commons Proper - 一个可复用的 Java 组件库 ...

  6. 常见 jar包详解

        常见 jar包详解 jar包 用途 axis.jar SOAP引擎包 commons-discovery-0.2.jar 用来发现.查找和实现可插入式接口,提供一些一般类实例化.单件的生命周期 ...

  7. Qt: The State Machine Framework 学习

    State Machine,即为状态机,是Qt中一项非常好的框架.State Machine包括State以及State间的Transition,构成状态和状态转移.通过状态机,我们可以很方便地实现很 ...

  8. Qt 状态机框架学习(没学会)

    Qt状态机框架是基于状态图XML(SCXML) 实现的.从Qt4.6开始,它已经是QtCore模块的一部分.尽管它本身是蛮复杂的一套东西,但经过和Qt的事件系统(event system).信号槽(s ...

  9. Qt状态机框架

    The State Machine Framework 状态机框架提供了用于创建和执行状态图的类.概念和符号是基于Harel的Statecharts: A visual formalism for c ...

随机推荐

  1. 关于SVN的操作批处理示例

    关于SVN的操作批处理示例 为了一句话:不要动手做机器能够做的事情. 天天工作用svn,更新啥的打开目录啥的动作天天在重复.每次写些命令也蛮无聊的,不说了,看下面: 1 @echo off 2 rem ...

  2. 网络流(最大流) POJ 1637 Sightseeing tour

    Sightseeing tour Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 8628   Accepted: 3636 ...

  3. bzoj1208 [HNOI2004]宠物收养所(STL,Treap)

    1208: [HNOI2004]宠物收养所 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 5956  Solved: 2317[Submit][Sta ...

  4. mac下的改装人生——把主硬盘换成ssd

    这两天搞得最多的事情就是我的这两块硬盘,基本上的时间都被他们占用去了,但是最后的结果也是让我很开心--开机瞬秒,程序瞬秒,生活质量瞬间高了很多哈. 关于ssd的各种事情,我的另外一篇博客有讲,算是比较 ...

  5. 《傲慢与偏见》(Pride and Prejudice)

    <傲慢与偏见>(Pride and Prejudice)改编自英国作家简·奥斯汀的同名小说,1940年上映.讲述了19世纪初期英国的一个普通的中产家庭中五姐妹的爱情与择偶故事.片中因为男主 ...

  6. [Locked] 3Sum Smaller

    3Sum Smaller Given an array of n integers nums and a target, find the number of index triplets i, j, ...

  7. android 客户端 和 新浪微博如何打通的

    微博SDK 为开发者 提供访问oauth2.0 授权认证,并集合sso登录功能,使用第三方应用可通过 新浪微博的 登录操作 提供微博分享功能,可直接通过微博客户端分享微博 名词解释 AppKey 分配 ...

  8. Java中sleep,wait,yield,join的区别

    sleep() wait() yield() join()用法与区别   1.sleep()方法 在指定时间内让当前正在执行的线程暂停执行,但不会释放“锁标志”.不推荐使用. sleep()使当前线程 ...

  9. git 在linux中的使用

    1,经常使用操作 一,clone远程仓库 比如clone test项目的分支v1.0 git -c diff.mnemonicprefix=false -c core.quotepath=false ...

  10. Android MVP框架模式

    结合前一篇MVC框架模式 为了更好地细分视图(View)与模型(Model)的功能,让View专注于处理数据的可视化以及与用户的交互,同时让Model只关系数据的处理,基于MVC概念的MVP(Mode ...