首页 > 编程语言 >带你0到1之QT编程:二十六、实战应用之翻转动画的实现

带你0到1之QT编程:二十六、实战应用之翻转动画的实现

时间:2024-11-15 19:19:03浏览次数:3  
标签:动画 QT 编程 transform 旋转 pix rotateVal 页面

此为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 简单实现槽函数,完成!

总:在这次开发中,主要运用了QT中的QPropertyAnimation动画系统、Q_PROPERTY属性系统(需要动态访问和修改对象的成员变量)、还有重绘事件来进行动画的实现

标签:动画,QT,编程,transform,旋转,pix,rotateVal,页面
From: https://blog.csdn.net/weixin_68122199/article/details/143220154

相关文章

  • Linux编程:基于 Unix Domain Socket 的进程/线程间通信实时性优化
    文章目录0.引言1.使用`epoll`边缘触发模式非不要不选择阻塞模式边缘触发(ET)模式优点示例2.使用实时调度策略3.CPU绑定4.使用无锁缓冲区5.优化消息传递的大小和频率6.使用`SO_RCVTIMEO`和`SO_SNDTIMEO`7.示例代码其他阅读0.引言前几天被问到“如何优......
  • C++编程:实现一个简单的消息总线
    文章目录0.引言1.设计思路1.1关键类设计1.2类图1.3时序图1.4流程图2.代码结构与设计2.1消息回调与订阅项2.2消息总线类`MessageBus`2.3定时任务调度器`PeriodicTaskScheduler`3.核心功能实现3.1消息发布3.2超时检查4.测试代码0.引言在之前的文......
  • 仓颉_Cangjie-函数式编程
    函数定义CC语言中,函数的声明告诉编译器函数的名称、返回类型和参数列表。函数的定义则提供了函数的实际体C++返回类型函数名(参数列表){//函数体//执行的操作//返回返回类型的值}Java函数的定义分为函数的声明和函数的实现Rust使用fn关键字定义函数。函......
  • CSAPP 并发编程
    frompixiv前置知识进程逻辑控制流(简称逻辑流)CSAPPP508:一系列的程序计数器PC的值唯一地对应于包含在程序的可执目标文件中的指令或包含在运行时动态链接到程序的共享对象指令。这个PC值的序列叫逻辑控制流一个逻辑流的执行在时间上与另一个流重叠,称为并发流,这两个流被......
  • pyqt5使用中的一些坑
    1、使用Qlabel显示rgb图像和灰度图像发生扭曲RGB:defdis_img(self):#BGR=>RGB文件格式shrink=cv2.cvtColor(self.img_org,cv2.COLOR_BGR2RGB)#cv图片转换成qt图片qt_img=QtGui.QImage(shrink.data,#数据源shrink.s......
  • Python并发编程入门:使用concurrent.futures与asyncio
    Python并发编程入门:使用concurrent.futures与asyncio在现代应用中,并发编程已成为一种提升性能和效率的重要手段。Python提供了多种实现并发的方式,尤其是concurrent.futures和asyncio,分别适用于不同的并发场景。本文将带你深入了解这两种并发编程方式,帮助你轻松上手并......
  • 深入探索 C++11 第一弹:现代 C++ 编程的基石与革新
    1、C++的发展历史C++11是C++的第⼆个主要版本,并且是从C++98起的最重要更新。C++11对C++语言的发展具有深远的影响,它使C++语言更加现代化、高效、灵活和易于使用,为开发者提供了更强大的工具和更好的编程体验,推动了C++在各个领域的广泛应用和持续发展。话不多说,下......
  • 第16章 Shell企业编程基础
    说到Shell编程,很多从事Linux运维工作的朋友都不陌生,都对Shell有基本的了解,初学者可能刚开始接触Shell的时候,有各种想法,感觉编程非常困难,SHELL编程是所有编程语言中最容易上手,最容易学习的编程脚本语言。本章向读者介绍Shell编程入门、Shell编程变量、If、While、For、Case......
  • 仓颉原生应用编程语言教程(第5期)
    泛型视频:KCKCJY在现代软件开发中,泛型编程已成为提高代码质量、复用性和灵活性的关键技术。泛型作为一种参数化多态技术,允许开发者在定义类型或函数时使用类型作为参数,从而创建可适用于多种数据类型的通用代码结构。泛型带来的好处包括:代码复用:能够定义可操作多种类型的通用算法......
  • Linux系统编译QT5.15.0及串口问题
    编译流程:1>下载QT源码源码的下载可以到qt的官网http://www.qt.io/download/ 2>解压tarxvfqt-everywhere-src-x.x.x.tar.gz注意后缀和解压方式3>配置 ./configure进行环境配制。4>编译执行make编译,时间长,大概在三四个小时左右。5>安装sudomakeinstall需要5分钟......