图形视图动画和状态机框架ppt课件.ppt

上传人:小飞机 文档编号:1967745 上传时间:2022-12-28 格式:PPT 页数:34 大小:1.07MB
返回 下载 相关 举报
图形视图动画和状态机框架ppt课件.ppt_第1页
第1页 / 共34页
图形视图动画和状态机框架ppt课件.ppt_第2页
第2页 / 共34页
图形视图动画和状态机框架ppt课件.ppt_第3页
第3页 / 共34页
图形视图动画和状态机框架ppt课件.ppt_第4页
第4页 / 共34页
图形视图动画和状态机框架ppt课件.ppt_第5页
第5页 / 共34页
点击查看更多>>
资源描述

《图形视图动画和状态机框架ppt课件.ppt》由会员分享,可在线阅读,更多相关《图形视图动画和状态机框架ppt课件.ppt(34页珍藏版)》请在三一办公上搜索。

1、Qt Creator快速入门第3版,第11章 图形视图、动画和状态机框架,高级的图形和动画应用框架图形视图框架(Graphics View Framework)动画框架(Animation Framework)状态机框架(State Machine Framework),11.1 图形视图框架的结构11.2 坐标系统和事件处理11.3 图形视图框架的其他特性11.4 动画框架11.5 状态机框架,主 要 内 容,11.1 图形视图框架的结构,基本绘图绘图完成后,无法控制图形元素。图形视图框架绘图完成后,可以控制图形项的移动、检测它们的碰撞和叠加等。比喻:基本绘图像在纸上画画,画完后很难更改。图

2、形视图框架像在板子上放拼图,不满意可以随时更改。,图形视图框架主要包含三部分:图形项(QGraphicsItem):是基本的绘图单元。图形视图框架为经典的形状提供了标准的图形项,如矩形(QGraphicsRectItem)、椭圆(QGraphicsEllipseItem) 、文本项(QGraphicsTextItem)等。(世界的组成元素)场景(QGraphicsScene ):是放置图形项对象的容器。可以调用addItem()函数向场景中添加图形项,场景对图形项进行管理。(真实世界)视图(QGraphicsView):用来使场景中的内容可视化。每个视图提供一个视口。对于同一个场景,可以使用不

3、同的视图对象实现不同的可视化效果。(不同的人、动物、甚至事物看到的世界),QGraphicsRectItem:提供一个矩形itemQGraphicsEllipseItem:提供一个椭圆itemQGraphicsPolygonItem:提供一个多边形itemQGraphicsLineItem:提供一条线的itemQGraphicsPathItem:提供一个任意的路径itemQGraphicsSimpleTextItem:提供一个文字图标itemQGraphicsTextItem:提供一个文本浏览itemQGraphicsPixmapItem:提供一个图形item,标准图形项,相关函数scene.

4、addItem(item):向场景中添加已有的图形项scene.addRect():新建标准图形项(矩形),并添加到场景中。scene.itemAt(QPoint):返回指定位置处最顶层可视的图形项。scene.items():返回满足特定条件的所有图形项。view.setForegroundBrush():设置视图的前景颜色。view.setBackgroundBrush():设置视图的背景颜色。view.scale()、rotate() 等:对视图进行仿射变换。QGraphicItemGroup:一个图形项组可以包含多个图形项,一个图形项组在场景中可以当作一个图形项使用。,自定义图形项若需

5、要使用标准图形项之外的图形,可以自定义图形项。步骤:子类化QGraphicsItem类;class MyItem : public QGraphicsItem 重新实现边界矩阵函数boundingRect();重新实现绘制函数paint()。,11.2.1 坐标系统,边界矩形(bounding rectangle)图形项、场景、视图都在各自的一个矩形框中。坐标原点(默认)图形项坐标:在其边界矩形的中心。场景坐标:在其边界矩形的中心。视图坐标:在其边界矩形的左上角。坐标轴x轴从左到右;y轴由上到下;z轴由内而外(图形项的z值越大,在场景中越靠上)。,相关函数item.setPos():设置图形项

6、在场景中的位置。item.pos():返回图形项在场景(父对象)中的位置。item.setZValue():设置图形项的Z值,Z值越大越靠上。坐标映射函数,11.2.2 事件处理与传播,事件的传播视图(QEvent)场景(QGraphicsSceneEvent)图形项事件在从视图到场景的传递过程中进行了类型转换。图形视图事件的类型,图形项接收的事件类型键盘事件:默认地,图形项不接收键盘事件;使用item.setFocus()或scene.setFocusItem(item) 使图形项item获得焦点,这样item就可以接收键盘事件。鼠标悬停事件:默认地,图形项不接收鼠标悬停事件;使用item.

7、setAcceptHoverEvents()使图形项接收鼠标悬停事件。鼠标事件:默认地,图形项接收鼠标事件。,11.3.1 图形效果,图形效果(QGraphicsEffect)通过在源对象(如一个图形项)和目标设备(如视图的视口)之间挂接渲染管道和一些操作来实现改变元素外观的效果。使用item.setGraphicsEffect(effect)函数在item上实现effect效果。标准图形效果类,原图,模糊,半透明,着色,阴影,11.3.2 动画、碰撞检测和图形项组,动画的实现方法一:使用动画框架(Animation Framework)自定义的MyItem类需要继承自QGraphicsObj

8、ect类,然后使用QPropertyAnimation类来实现属性渐变动画。方法二:重新实现函数timerEvent()自定义的MyItem类继承自QObject和QGraphicsItem类,这样item就可以安装计时器,并在timerEvent()中实现累积动画。方法三:重新实现advance()函数此处介绍的方法周期性地调用Scene的advance()函数,它会进而周期性地调用item的advance()函数。,QGraphicsScene:advance()场景类QGraphicsScene的槽函数,通过调用场景中图形项的QGraphicsItem:advance()函数,将场景推进

9、一步。推进过程分为两个阶段:第一阶段:告知所有图形项,场景将要变化。传递phase=0给图形项第二阶段:告知所有图形项,它们可以移动了。传递phase=1给图形项触发方式:QObject:connect(QGraphicsItem:advance()图形项类QGraphicsItem的虚函数,对于场景中所有图形项来说,该函数被场景的槽函数调用两次。默认该函数什么也不做;若需要动画效果则需重构该函数。,碰撞检测方法一:先重新实现QGraphicsItem类的shape()函数返回图形项的准确形状,然后使用collidesWithItem()函数判断两个图形项形状之间是否有交集。shape与bou

10、ndingRect的区别:对于矩形来说,二者相同;对于其他图形来说,shape的区域小于boundingRect。方法二:直接重新实现QGraphicsItem类的collidesWithItem()函数,来提供一个自定义的图形项碰撞算法。,几个函数item.collidesWithPath(path,mode):判断item是否与path碰撞。item.collidesWithItem(item2,mode):判断item是否与item2碰撞。item.collidingItems(mode):获取与item碰撞的所有图形项的列表,返回类型为QList。modeQt:ItemSelectio

11、nModeQt:ContainsItemShape:“形状”完全包含在选定区域内的图形项Qt:IntersectsItemShape:“形状”包含在内或者与选定区域的边界相交的图形项。Qt:ContainsItemBoundingRect:“边界矩形”完全包含在选定区域内的图形项。Qt:IntersectsItemBoundingRect:“边界矩形”包含在内或者与选定区域的边界相交的图形项。,11.3.4 图形窗口部件,QGraphicsWidget与QWidget类似的图形部件。支持事件、信号与槽、尺寸提示和策略的部件。其对象既拥有窗口部件的特性,又拥有图形项的特性。继承关系,部件转换向场

12、景中添加普通部件,会生成一个对应的图形部件。QTextEdit *edit = new QTextEdit;QGraphicsWidget *textEdit = scene.addWidget(edit);图形部件可以进行坐标变换QGraphicsWidget *form = new QGraphicsWidget;form-shear(2, -0.5);,动画框架Animation Framework,11.4 动画框架,动画框架提供一种“创建具有平滑动画效果的GUI界面”的方法。该框架通过控制Qt中对象的属性来实现动画。应用场景:窗口部件、QObject对象、图形视图框架等。继承关系,Q

13、VariantAnimation支持的属性数据类型Int、Double、FloatQLine、QLineF、QPoint、QPointFQSize、QSizeF、QRect、QRectFQColor例子QPropertyAnimation animation(,QPropertyAnimation类使用缓和曲线对属性进行插值,从而实现动画效果。缓和曲线:对象属性随时间t的变化速度函数,默认是线性变化。Qt还定义了十几种类型的变化函数。每一种函数,又有In、Out、InOut和OutIn四种变化规律。,相关函数anim.setDuration(t):设置动画的持续时间。anim.setStart

14、Value(p0):设置动画开始时属性的值。anim.setEndValue(p1):设置动画结束时属性的值。anim.setKeyValueAt(a,pa):设置动画中间处属性的值。anim.setEasingCurve():设置动画使用的缓和曲线。anim.start():开始运行动画。动画组QSequentialAnimationGroup:顺序动画组QParallelAnimationGroup:平行动画组group.addAnimation(anim):向动画组中添加动画,11.5 状态机框架,状态机框架提供了一些类来创建和执行状态图(状态转移图)。状态图是一个用来表现“系统对外界激

15、励进行反应”的图形化模型。一个简单的状态机,向状态机machine中添加状态:以状态机为参数:QState s1=new QState(&machine)使用addState()函数:machine.addState(s1)设置“在状态s1下”部件的属性值s1-assignProperty(部件,属性名,属性值)例:s1-assignProperty(&button,“geometry”,QRect(0,0,100,100)设置状态间的转移关系s1-addTransition(&button,SIGNAL(clicked(),s2)转移关系:从s1转移到s2。转移条件:当button发射cli

16、cked()信号时。设置初始状态setInitialState(s1):将状态s1设置为初始状态。,与状态相关的信号进入状态s1时,s1会发射一个entered()信号。离开状态s1时,s1会发射一个exited()信号。若s1是QFinalState的对象,进入s1时会发射一个finished()信号。可以利用这些信号做一些事情,如:connect(s3, SIGNAL(entered(), button, SLOT(showMaximized(); connect(s3, SIGNAL(exited(), button, SLOT(showMinimized();,在状态机中使用动画,所有

17、状态都使用默认动画转移machine.addDefaultAnimation(animation);为不同状态定制专属动画转移transition1-addAnimation(animation1);transition2-addAnimation(animation2);注意:此处无需指定animation的开始值和结束值,它们隐含在切换所连接的两个状态中。,多个状态共享切换,“在任何状态下点击quitButton都退出”的实现方法:分别切换:分别从s11、s12、s13到状态s2添加切换:太繁琐共享切换:将s11、s12、s13聚合为一个新状态s1,然后添加s1到s2的切换,即可实现三个子

18、状态共享切换的效果。QState *s11 = new QState(s1); QState *s12 = new QState(s1); QState *s13 = new QState(s1); s1-setInitialState(s11); machine.addState(s1);machine.addState(s2); s1-addTransition(quitButton, SIGNAL(clicked(), s2);,被中断状态的保存与恢复,QHistoryStates1被中断后切换到s3,若希望s3执行后可以恢复到s1被中断时的子状态,可以使用历史状态来存储被中断时s1所处

19、的子状态。QHistoryState是一个伪状态,用来存储父状态退出时的子状态。QHistoryState *s1h = new QHistoryState(s1);s3-addTransition(s1h);machine.addState(s3);s1-addTransition(interruptButton, SIGNAL(clicked(), s3);,平行状态组避免组合爆炸,组合爆炸:若每个状态由n个属性组成(每个属性有两个互斥的取值),则共有2n个状态,状态个数随着n指数增长。平行状态组:每个属性一个子状态QState *s1 = new QState(QState:Parall

20、elStates);QState *s11 = new QState(s1);QState *s12 = new QState(s1);进入和退出平行状态组当进入一个平行状态组时,相当于同时进入了它的所有子状态。当一个子状态退出时,其他所有子状态都会退出。,无目标切换,使用重载形式s1-addTransition(trans) 进行无目标切换。相当于到自身的切换,即先退出s1,再进入s1。trans会发出triggered()信号。s1会发出exited()和entered()信号。利用这些信号可以进行一些处理。QSignalTransition *trans = new QSignalTransition(,The End !,

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 生活休闲 > 在线阅读


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号