Qt 简单开机动画实现流程

Qt中有一个Graphics View框架,使用这个框架,我们可以做一个简单的小启动动画。这篇文章不在于实现这个效果,而注重于实现过程发现的问题、解决思路以及对整个框架的理解。

1.创建场景、视图

我们需要创建一个开机动画,首先需要有地方来进行动画的显示,所以添加了视图、但这里的视图只有显示功能,所以我们还需要添加一个能够放置动画元素的地方,也就是场景。

2.设置场景

创建场景后,我们可以根据我们的需要,进行添加动画的背景了。但此时会出现问题,单纯添加背景后,背景图片会显示不正常,这是由于场景的坐标体系(以窗口中心为原点)与视图的坐标体系(以窗口左上角为原点)不同,造成了显示异常。

图 1setSenceRect可以看做是:将(无限大的)场景设置为width*height大小的矩形框,起始位置在view的(0,0)

3.创建图元

有了背景与视图后,我们还需要添加开机动画中的需要元素,即图元。在此之前,我们需要先创建图元,但尝试使用QGraphicsItem创建对象时,会发现无法创建对象。因为QGraphicsItem类中有两个纯虚函数,分别是:

QRectF  boundingRect() = 0;   以及  void  paint() = 0;

所以,QGraphicsItem是一个抽象类,这就需要我们去自己写一个继承于此类的派生类,并重定义这两个纯虚函数,才能创建图元对象。

4.添加图元到场景、设置位置

创建好图元后,我们要将他们添加到场景中,才能进行显示。但我们会发现,图元的坐标体系与场景相同,而不同于视图。可是我们在添加图元时并没有进行坐标转换,也可以显示到正常位置,这是因为,此时的setPos是相对于视图的,我们是在视图类构造中创建的图元对象,所以类似于我们在添加控件时的操作,传入的坐标是相对于视图的坐标,也就不需要坐标转换。

5.移动图元、碰撞检测

创建好图元后,我们需要实现的操作是两个图元碰撞后停下,并弹出确认窗口。

首先我们需要对图元进行移动,Qt中有提供一个用于移动图元的虚函数advance(),x为正则向右移动,x为负则向左移动,y同理。但与上面不同的是,此时我们的移动是基于图元自身坐标的移动,就需要我们进行坐标转换,Qt也为我们提供了这样一个函数mapToScene(),可以进行坐标转换。

而我们需要制作的是一个动画,我们必须多次、自动地调用advance函数,所以我们使用Qt中的计时器,设置了间隔时间20ms,每当到达设定时间之后就发送信号timeout();调用槽函数advance();实现图元的动画效果

通过advance函数偏移后,我们要检测移动后的两个图元是否碰撞,我们就需要使用Qt中的另一个函数collidingItems();进行碰撞检测,

这个函数的返回值是一个图元类的链表容器,所以我们只需要判断容器的元素数量即可。

接着,碰撞之后会emit sendStop()信号,这个信号用于停下计时器。但实现时出现弹窗两次的现象,查阅Qt官方手册后发现,是由于此处advance函数会自动调用两次,一次phase==0,另一次phase==1,函数中自带的phase就是用来判断此次调用是advance前还是advance后的,所以我们只需判断选择其中一次发送sendStop()信号即可。

另外,我们需要进行弹窗提示,所以又重新写了一个槽函数closeTime();在里面关闭计时器,并且使用QMessageBox的静态成员information,再在弹窗后显示Login窗口。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值