此为QT编程的第二十六谈!关注我,带你快速学习QT编程的学习路线!
每一篇的技术点都是很很重要!很重要!很重要!但不冗余!
我们通常采取总-分-总和生活化的讲解方式来阐述一个知识点!
码农不易,各位学者学到东西请点赞支持支持!
开始部分:
总:在开发过程中,难以避免有些高级动画的实现,例如翻转、平移等等。这篇文章将教你们如何实现两个页面如何翻转在同一个对话框。
预设效果如下:
<iframe allowfullscreen="true" data-mediaembed="csdn" frameborder="0" id="5XdNRwTN-1731668757598" src="https://live.csdn.net/v/embed/434265"></iframe>qt的动画旋转demo
分:那么就开始实现这个效果吧!
一、完成页面小模块
1、首先,我需要构建两个页面的模块QWdiget,命名为page1、page2
2、创建完成后,直接去各自的.UI文件添加翻转按钮
3、此时已经完成一半咯!现在完成背景部分,那么就重写QPaintEvent
4、在cpp文件实现即可,此时能看见背景图啦(资源的话自己添加资源文件噢)
5、最重要的是信号触发!当我们点击按钮(转到槽)的时候,触发这个信号,留给存放QWidget的对话框来接收!
此刻的page模块已经完成了,恭喜!page2同理完成即可!
二、利用Qt自带的QStackedWidget来完成动画实现
1、那么这时候我们就要创建一个来实现动画效果的QStackedWidget了,其实也是一个小模块,用来存放page1、page2,并继承了QStackedWidget
2、这时候你需要在.h文件添加QStackWidget头文件
3、我们要如何实现动画呢?本质就是利用绘制事件咯,就如重写背景QPaintEvent,并利用qt自带的QPropertyAnimation动画机制来实现
3.1 先设计好AnimateStackedWidget这个头文件,由于需要使用信号与槽,添加Q_OBJECT宏,和QPROPERTY宏来定义rotateVal旋转角度
3.2 声明paintEvent函数、animation动画启动函数、还有设置旋转起始值、旋转结束值、获取旋转起始值、旋转结束值、获取旋转角度、设置旋转角度
3.3 再自定义成员变量、和自定义槽函数
3.4 此时的头文件基本完成了,这时候就实现函数即可!
3.4.1 先在构造函数设置初始页码、和动画状态
3.4.2 再实现动画启动函数,创建一个QPropertyAnimation对象,来设置起始值、结束值、动画持续性、动画柔和曲线。当旋转角度发生变化的时候,调用对应槽函数;动画完成后,调用对应槽函数
3.4.3 先实现简单的槽函数,本质就是随旋转值的变化,而重复调用绘制事件;还有完成之后,调用基类的QStackedWidget的一些函数,将反面设置到正面
3.4.4 万事俱备,只欠东风!此刻完成绘制事件即可!
// 自定义的绘制事件,负责绘制动画效果
void AnimateStackedWidget::paintEvent(QPaintEvent *event)
{
QPainter p(this); // 创建一个 QPainter 对象 p,用于在当前控件上绘制,p 是绘制的工具
// 判断当前旋转角度是否在 0 到 90 度之间
if (m_rotateVal > 0 && m_rotateVal <= 90) {
QPixmap pix(currentWidget()->size()); // 创建一个与当前页面大小相同的 QPixmap 对象(缓存当前页面内容)
currentWidget()->render(&pix); // 将当前页面渲染到 QPixmap 中,pix 存储当前页面的图像
// 创建一个 QTransform 对象,用于旋转和移动图片
QTransform transform;
transform.translate(width()/2, 0); // 平移坐标系原点到控件的中心,旋转会围绕这个点进行
transform.rotate(m_rotateVal, Qt::YAxis); // 沿 Y 轴旋转 m_rotateVal 角度,旋转当前页面
p.setTransform(transform); // 应用旋转变换,p 设置为旋转后的状态
// 将旋转后的图像绘制到控件上,图像的左上角位置会根据平移来保证图片居中显示
p.drawPixmap(-width()/2, 0, pix); // 将图像绘制到左上角,偏移量为 -width()/2 保证旋转中心对准控件中心
} else if (m_rotateVal > 90 && m_rotateVal <= 180) {
// 如果旋转角度在 90° 到 180° 之间,处理翻转到背面的效果
QPixmap pix(widget(m_pageindex)->size()); // 创建一个与目标页面大小相同的 QPixmap 对象
widget(m_pageindex)->render(&pix); // 渲染目标页面的内容到 pix 中
// 创建旋转变换
QTransform transform;
transform.translate(width()/2, 0); // 将坐标系原点平移到控件的中心,旋转会围绕这个点
transform.rotate(m_rotateVal + 180, Qt::YAxis); // 旋转角度增加 180°,达到从正面翻转到背面的效果
p.setTransform(transform); // 应用旋转变换
// 绘制旋转后的图像
p.drawPixmap(-width()/2, 0, pix); // 在指定位置绘制图像,确保图像居中显示
}
else if (m_rotateVal > -180 && m_rotateVal <= -90) { // 反向旋转,旋转角度从 -180° 到 -90° 之间
QPixmap pix(widget(m_pageindex)->size()); // 获取目标页面的 QPixmap 缓存
widget(m_pageindex)->render(&pix); // 渲染目标页面内容到 pix 中
// 创建旋转变换
QTransform transform;
transform.translate(width()/2, 0); // 平移坐标系原点到控件的中心
transform.rotate(m_rotateVal + 180, Qt::YAxis); // 旋转角度加 180°,模拟从背面翻转回正面
p.setTransform(transform); // 应用旋转变换
// 绘制旋转后的图像
p.drawPixmap(-width()/2, 0, pix); // 在指定位置绘制图像
} else if (m_rotateVal > -90 && m_rotateVal < 0) {
// 处理从负角度 -90° 到 0° 之间的旋转
QPixmap pix(currentWidget()->size()); // 获取当前页面的 QPixmap 缓存
currentWidget()->render(&pix); // 渲染当前页面内容到 pix 中
// 创建旋转变换
QTransform transform;
transform.translate(width()/2, 0); // 平移坐标系原点到控件的中心
transform.rotate(m_rotateVal, Qt::YAxis); // 沿 Y 轴旋转 m_rotateVal 角度
p.setTransform(transform); // 应用旋转变换
// 绘制旋转后的图像
p.drawPixmap(-width()/2, 0, pix); // 在指定位置绘制图像,确保图像居中显示
}
}
分为两个部分:一个是正向旋转,一个是反向旋转
4.完成以上模块,就可以在对话框中调用这个自定义控件了
4.1 先创建一个对话框的类
4.2 完成后,在.h文件导入刚刚实现的三个类,page1、page2、animateStackedWidget的头文件,声明三个类成员,声明接收到page1、page2发出的信号后对应的槽函数
4.3 最后一步!完成.cpp文件,在构造函数设置一些UI属性、将page1、page2添加到animateStackedWidget中,再将animateStackedWidget添加到水平布局管理中、还记得page中emit发出的信号吗?就在这里连接槽函数
4.4 简单实现槽函数,完成!