Qt 状态机框架学习(没学会)
Qt状态机框架是基于状态图XML(SCXML) 实现的。从Qt4.6开始,它已经是QtCore模块的一部分。尽管它本身是蛮复杂的一套东西,但经过和Qt的事件系统(event system)、信号槽(signals and slots)及属性系统(property system)深度整合,它使用门槛并不高。
一些概念
Qt的手册中The State Machine Framework一文对Qt状态机框架及使用进行了介绍,可是还是发现看看基本的概念(详见 SCXML 的 第三部分 )更有帮助一点。
基本概念
最基本的概念是:
- 状态(state)
- 转换?过渡?(transition)
- 事件(events)
每一个state包含一个transition的集合,这些transition定义了如何对events进行响应。events可以由状态机本身或外部实体产生。
在一个经典状态机中,状态机总是处于一个单一的state中。这个状态被称为active state。当event发生时,状态机将检查active state的包含的所有transition。如果它发现有一个和该event匹配,状态机将从当前的active state移动到该transition指定的state(称之为transtion的目标)。这样一来,目标state将成为新的active state。
在transition的过程中,状态机可以执行一些动作(action)。每一个状态都可以包含onentry 和 onexit动作,transition本身也可以包含动作。当状态机通过一个名为T的transition从状态S1转换到S2,它先执行S1的 onexit 的动作,然后执行T本身包含的动作,最后执行S2 onentry的动作。
Compound States
一个state还可以嵌套其他的state。这样的state称为compound states(复合状态),我们称其为parent state,而被嵌套的则称为child state。子state又可以嵌套其他的state,直到任意深度。不包含任何子state的state,称为atomic state(原子状态)。
当一个child state处于 acitve时,它的parent active 也必须处于active状态。这样一来,在任何一点我们都将拥有一个包含原子state和它所有祖先的active state的集合。(在后面我们将看到多个原子state可以同时处于active状态)。
由于复合state的存在,transition将不再是从一个原子state到另一个原子state的转换,而是从一个active state集合到另一个集合的转换。如果transition的目标是一个原子state,那么状态机将不仅进入到该原子state,而且还将进入到它所有的为处于active的祖先state中。与此对应的是,transition的目标是一个组合state。在这种情况下,复合state的子state必须也被激活,由于transition并没有指定哪一个,这是需要active该复合state的initial state(初始状态)。如果该state依然是复合状态,将递归下去,直到原子 state。
一个复合state还可以包含final 和 history state作为其child state。
复合状态还会影响到transition的选择。当事件发生时,状态机从最深层嵌套的state(原子state)开始查找,如果未找到匹配的transition,则查找其parent state的transition,依次递归。如果状态机中所有transition均不匹配,事件被丢弃。
Parallel States
注:在SCXML中 Parallel States使用的是paralled 标签,前面提到的复合state和原子state都是用的state 标签。在Qt中,Paralled State和普通 state 是靠构造函数一个的参数进行区分的。
Parallel States(平行状态) 与前面介绍的复合 state 有很大的不同:当一个复合state处于active时,有且只有一个child state处于acitve;而parallel state处于active时,所有的child state都必须处于active状态。
当状态机进入平行state时,它也进入各个child state。各个child state可以采取不同的transition对event进行响应。
Executable Content
SCXML通过Executable Content(可执行内容?)提供了对数据(data model)进行修改和与外界实体进行交互的功能。
回到 Qt
这部分内容Qt Manual中给的太详细了,以至于都不知道该怎么向下写了。
基本概念
3个基本概念对照:
state |
QAbstractState及其派生类 |
transition |
QAbstractTransition及其派生类 |
event |
Qt的信号和事件 |
data |
Qt属性 |
注意:QStateMachine本身是QState的派生类。这使得状态机可以嵌套,见qstatemachines-a-state-too 。
- QObject
- QAbstractState
- QState
- QStateMachine
- QFinialState
- QHistoryState
- QState
- QAbstractTransition
- QSignalTransition
- QEventTransition
- QKeyEventTransition
- QMouseEventTransition
- QAbstractState
- QEvent
QStateMachine::SignalEvent
QStateMachine::WrappedEvent
transition的触发
Qt的信号和事件都可以触发transition。那么是如何实现的呢?
打开QAbstractTransition的Manual,可以看到两个protected的函数:
virtual bool eventTest ( QEvent * event ) = 0
virtual void onTransition ( QEvent * event ) = 0
前者用来判断事件是否匹配,后者用来执行一些动作。
两个具体类和对应的QEvent的派生类关系如下:
QSignalTransition |
QStateMachine::SignalEvent |
QEventTransition |
QStateMachine::WrappedEvent |
进入状态后,状态机将active state的对应的transition进行注册:
对于signal类型的,将该信号连接到一个私有槽函数,槽函数中生成一个内部的QStateMachine::SignalEvent事件
对于event类型的,将直接在事件的对象安装事件过滤器,将事件拷贝并封装到一个内部的QStateMachine::WrappedEvent事件中。
对于自定义事件,可以使用QStateMachine::postEvent()进行派发。
参考
http://labs.qt.nokia.com/2009/07/23/qstatemachines-a-state-too/
http://labs.qt.nokia.com/2009/11/09/about-dynamic-ui-web-apps-performance-and-state-machines/
http://labs.qt.nokia.com/2009/01/30/qt-state-machine-framework/
http://blog.csdn.net/dbzhang800/article/details/6408008
Qt 状态机框架学习(没学会)的更多相关文章
- Qt状态机框架(状态机就开始异步的运行了,也就是说,它成为了我们应用程序事件循环的一部分了)
状态机框架 Qt中的状态机框架为我们提供了很多的API和类,使我们能更容易的在自己的应用程序中集成状态动画.这个框架是和Qt的元对象系统机密结合在一起的.比如,各个状态之间的转换是通过信号触发的,状态 ...
- Qt状态机框架
The State Machine Framework 状态机框架提供了用于创建和执行状态图的类.概念和符号是基于Harel的Statecharts: A visual formalism for c ...
- 如何保证Qt状态机的最佳性能
如何保证Qt状态机的最佳性能 How to ensure the best Qt state machine performance 如果您使用Qt进行应用程序开发,并且使用状态机,那么很可能您正在使 ...
- Qt 智能指针学习(7种指针)
Qt 智能指针学习 转载自:http://blog.csdn.net/dbzhang800/article/details/6403285 从内存泄露开始? 很简单的入门程序,应该比较熟悉吧 ^_^ ...
- QT皮肤框架-TQUI
本皮肤框架的相关文档,请在附件中下载,包括测试程序源码,帮助文档.相关文档可到我的百度网盘中下载,或者在本贴附件中下载. 百度网盘地址:TQUI-V1.0项目说明及测试程序源码 项目更新说明:---- ...
- Spring框架学习1
AnonymouL 兴之所至,心之所安;尽其在我,顺其自然 新随笔 管理 Spring框架学习(一) 阅读目录 一. spring概述 核心容器: Spring 上下文: Spring AOP ...
- JavaSE中Collection集合框架学习笔记(2)——拒绝重复内容的Set和支持队列操作的Queue
前言:俗话说“金三银四铜五”,不知道我要在这段时间找工作会不会很艰难.不管了,工作三年之后就当给自己放个暑假. 面试当中Collection(集合)是基础重点.我在网上看了几篇讲Collection的 ...
- JavaSE中Collection集合框架学习笔记(3)——遍历对象的Iterator和收集对象后的排序
前言:暑期应该开始了,因为小区对面的小学这两天早上都没有像以往那样一到七八点钟就人声喧闹.车水马龙. 前两篇文章介绍了Collection框架的主要接口和常用类,例如List.Set.Queue,和A ...
- JavaSE中线程与并行API框架学习笔记——线程为什么会不安全?
前言:休整一个多月之后,终于开始投简历了.这段时间休息了一阵子,又病了几天,真正用来复习准备的时间其实并不多.说实话,心里不是非常有底气. 这可能是学生时代遗留的思维惯性--总想着做好万全准备才去做事 ...
随机推荐
- Codeforces Round #261 (Div. 2)——Pashmak and Buses
题目链接 题意: n个人,k个车,d天.每一个人每天能够坐随意一个车.输出一种情况保证:不存在两个人,每天都在同一辆车上 (1 ≤ n, d ≤ 1000; 1 ≤ k ≤ 109). 分析: 比赛中 ...
- 关于js的一些总结
1.js中如果判断变量是否为空,要注意两种情况: 一种是变量为空:另一种是变量为0: 2.js如果要进行算术运算或者比较,最好把它强制类型为整型或者浮点型.防止字符串比较,如果本来是数字的字符串,如果 ...
- CSS样式表基础知识、样式表的分类及选择器
一.CSS基本概念: CSS(Cascading Style Sheet,叠层样式表),作用是美化HTML网页. /*注释区域*/ 此为注释语法 二.样式表的分类 1.内联样式表(和html联合 ...
- C#中常量\枚举\结构及数组的运用
又一天结束了,今天在云和学院学习的知识下面继续来做总结. 一.常量\枚举\结构的运用 理论: 常量:const 类型 常量名 = 常量值 确定数量.确定值的几个取值:东西南北.男女.上中下. 枚举: ...
- Xcode - 内存分析
内存分析工具 1. ARC中的内存泄露 1. 一般内存分析, 主要是看看有没有内存泄露 2. 内存泄露: 创建了对象, 使用完毕没有释放, 将来就可能造成内存泄露 3. 内存泄露: 主要用于MRC的内 ...
- CodeForces 443B Kolya and Tandem Repeat
题目:Click here 题意:给定一个字符串(只包含小写字母,并且最长200)和一个n(表示可以在给定字符串后面任意加n(<=200)个字符).问最长的一条子串长度,子串满足前半等于后半. ...
- STL之deque(双向队列)
deque双向队列是一种双向开口的连续线性空间,可以高效的在头尾两端插入和删除元素,deque在接口上和vector非常相似,下面列出deque的常用成员函数: deque在vector函数的基础上增 ...
- 初探响应式Web设计
公司书柜有本<响应式Web设计:HTML5和CSS3实战>,大概就认真看了前面几章,后面大部分介绍css3(随便找本手册都可以了要你可用!) <响应式Web设计:HTML5和CSS3 ...
- js中设置setInterval的注意点
<html> <head> <meta http-equiv="Content-Type" content="text/html; char ...
- 让我们共同构筑物联网起飞的平台:物联网操作系统Hello China寻求应用合作伙伴
经过几天的努力,终于把Hello China V1.76版的内核移植到基于Cortex-M3内核的STM32 chipset上.因为还希望进一步写一个USART驱动程序,因此详细的移植文档,预计一周之 ...