Qt进阶开发:动画框架的介绍和使用

文章目录

    • 一、QPropertyAnimation 简介
    • 二、基本用法
    • 三、常用属性和方法
    • 四、支持的属性(部分常用)
    • 五、多个动画组合
    • 六、使用缓和曲线
    • 七、状态机框架

一、QPropertyAnimation 简介

#include <QPropertyAnimation>
  • QPropertyAnimation 可以让你在一段时间内平滑地修改对象的属性值。
  • 支持 QWidget 的 geometry、pos、size、windowOpacity 等属性。
  • 它基于 Qt 的 属性系统(Q_PROPERTY),只能操作那些被 Q_PROPERTY 宏声明过的属性。

二、基本用法

例子:让一个按钮平滑移动位置

QPushButton *button = new QPushButton("Click Me", this);
button->move(0, 0);QPropertyAnimation *animation = new QPropertyAnimation(button, "pos");
animation->setDuration(1000);                    // 动画持续 1000ms
animation->setStartValue(QPoint(0, 0));          // 起始位置
animation->setEndValue(QPoint(200, 200));        // 结束位置
animation->start();                              // 启动动画

例子:让一个按钮平滑移动并且变大

#include <QPushButton>
#include <QPropertyAnimation>MainWindow::MainWindow(QWidget *parent): QWidget(parent)
{this->setFixedSize(800, 600);QPushButton* pBtn = new QPushButton("Animated Button", this);QPropertyAnimation *pAnimation = new QPropertyAnimation(pBtn, "geometry");pAnimation->setDuration(1000);pAnimation->setStartValue(QRect(0, 0, 120, 30));pAnimation->setEndValue(QRect(250, 250, 200, 60));pAnimation->start(QAbstractAnimation::DeleteWhenStopped);}

三、常用属性和方法

在这里插入图片描述

四、支持的属性(部分常用)

在这里插入图片描述

五、多个动画组合

  在一个应用中经常会包含多个动画,例如,要同时移动多个图形项或者让它们一个接一个地串行移动。使用QAnimationGroup类可以实现复杂的动画,它的两个子类 QSequentialAnimationGroup和QParallelAnimationGroup分别提供了串行动画组和并行动画组。

5.1 QParallelAnimationGroup 的使用
QParallelAnimationGroup 是 Qt 动画框架(Qt Animation Framework)中的一个类,用于并行执行多个动画,即多个属性动画同时发生。

#include <QParallelAnimationGroup>
  • 它继承自 QAnimationGroup。
  • 内部可以添加多个 QPropertyAnimation(或其它动画)。
  • 所有动画会同时启动,彼此独立但并行执行。

基本使用示例:
示例:按钮同时平移、缩放、透明度变化

QPushButton *button = new QPushButton("Animate", this);
button->resize(100, 30);
button->move(50, 50);// 位置动画
QPropertyAnimation *posAnim = new QPropertyAnimation(button, "pos");
posAnim->setDuration(1000);
posAnim->setStartValue(QPoint(50, 50));
posAnim->setEndValue(QPoint(200, 150));// 大小动画
QPropertyAnimation *sizeAnim = new QPropertyAnimation(button, "size");
sizeAnim->setDuration(1000);
sizeAnim->setStartValue(QSize(100, 30));
sizeAnim->setEndValue(QSize(200, 60));// 透明度动画(需设置 WA_TranslucentBackground + setWindowOpacity)
QPropertyAnimation *opacityAnim = new QPropertyAnimation(button, "windowOpacity");
opacityAnim->setDuration(1000);
opacityAnim->setStartValue(1.0);
opacityAnim->setEndValue(0.3);// 并行动画组
QParallelAnimationGroup *group = new QParallelAnimationGroup(this);
group->addAnimation(posAnim);
group->addAnimation(sizeAnim);
group->addAnimation(opacityAnim);group->start();

常用方法和属性:
在这里插入图片描述

完整示例:

#include <QPushButton>
#include <QPropertyAnimation>
#include <QParallelAnimationGroup>MainWindow::MainWindow(QWidget *parent): QWidget(parent)
{this->setFixedSize(800, 600);this->setWindowTitle("动画");QPushButton *button = new QPushButton("Animate Me", this);button->resize(100, 30);button->move(50, 50);// 动画 1:移动QPropertyAnimation *moveAnim = new QPropertyAnimation(button, "pos");moveAnim->setDuration(1000);moveAnim->setStartValue(QPoint(50, 50));moveAnim->setEndValue(QPoint(200, 150));// 动画 2:缩放QPropertyAnimation *sizeAnim = new QPropertyAnimation(button, "size");sizeAnim->setDuration(1000);sizeAnim->setStartValue(QSize(100, 30));sizeAnim->setEndValue(QSize(200, 60));// 动画 3:透明度QPropertyAnimation *opacityAnim = new QPropertyAnimation(button, "windowOpacity");opacityAnim->setDuration(1000);opacityAnim->setStartValue(1.0);opacityAnim->setEndValue(0.4);// 并行动画组QParallelAnimationGroup *group = new QParallelAnimationGroup;group->addAnimation(moveAnim);group->addAnimation(sizeAnim);group->addAnimation(opacityAnim);QObject::connect(button, &QPushButton::clicked, [group]() {group->start(QAbstractAnimation::KeepWhenStopped);});
}

5.2 QSequentialAnimationGroup 的使用
QSequentialAnimationGroup 是 Qt 动画框架(Qt Animation Framework)中的一个动画组类,用于 顺序地执行多个动画 —— 即一个动画结束后,自动执行下一个动画,依此类推。它特别适用于需要连续步骤式动画效果的场景,比如一个按钮先移动 → 再放大 → 再变淡。

#include <QSequentialAnimationGroup>
  • 它继承自 QAnimationGroup。
  • 内部包含多个动画(如 QPropertyAnimation)。
  • 每个动画顺序执行,一个结束后自动播放下一个。

基本使用示例:
示例:按钮先移动 → 再变大 → 再淡出

QPushButton *button = new QPushButton("Animate", this);
button->move(50, 50);
button->resize(100, 30);// 动画 1:移动
QPropertyAnimation *moveAnim = new QPropertyAnimation(button, "pos");
moveAnim->setDuration(1000);
moveAnim->setStartValue(QPoint(50, 50));
moveAnim->setEndValue(QPoint(200, 150));// 动画 2:缩放
QPropertyAnimation *sizeAnim = new QPropertyAnimation(button, "size");
sizeAnim->setDuration(800);
sizeAnim->setStartValue(QSize(100, 30));
sizeAnim->setEndValue(QSize(200, 60));// 动画 3:透明度
QPropertyAnimation *opacityAnim = new QPropertyAnimation(button, "windowOpacity");
opacityAnim->setDuration(800);
opacityAnim->setStartValue(1.0);
opacityAnim->setEndValue(0.3);// 顺序动画组
QSequentialAnimationGroup *group = new QSequentialAnimationGroup(this);
group->addAnimation(moveAnim);
group->addAnimation(sizeAnim);
group->addAnimation(opacityAnim);group->start();

常用方法:
在这里插入图片描述
插入等待/暂停动画:
可以在两个动画之间插入暂停

group->addAnimation(moveAnim);
group->insertPause(500);  // 停 500ms
group->addAnimation(sizeAnim);

完整可运行示例:

#include <QPushButton>
#include <QPropertyAnimation>
#include <QSequentialAnimationGroup>MainWindow::MainWindow(QWidget *parent): QWidget(parent)
{this->setFixedSize(800, 600);this->setWindowTitle("动画");QPushButton *button = new QPushButton("Start Animation", this);button->move(50, 50);button->resize(100, 30);// 动画组定义QSequentialAnimationGroup *group = new QSequentialAnimationGroup;// 移动动画QPropertyAnimation *moveAnim = new QPropertyAnimation(button, "pos");moveAnim->setDuration(1000);moveAnim->setStartValue(QPoint(50, 50));moveAnim->setEndValue(QPoint(200, 150));// 暂停动画group->addAnimation(moveAnim);group->insertPause(1, 500);// 缩放动画QPropertyAnimation *sizeAnim = new QPropertyAnimation(button, "size");sizeAnim->setDuration(800);sizeAnim->setStartValue(QSize(100, 30));sizeAnim->setEndValue(QSize(200, 60));group->addAnimation(sizeAnim);// 透明度动画QPropertyAnimation *opacityAnim = new QPropertyAnimation(button, "windowOpacity");opacityAnim->setDuration(1000);opacityAnim->setStartValue(1.0);opacityAnim->setEndValue(0.3);group->addAnimation(opacityAnim);QObject::connect(button, &QPushButton::clicked, [group]() {group->start(QAbstractAnimation::KeepWhenStopped);});
}

补充说明:

  • 动画可重复播放:group->setLoopCount(n);
  • 动画结束信号:connect(group, &QSequentialAnimationGroup::finished, …)
  • 可嵌套其他动画组形成复杂流程(如先顺序 → 同时多个动画)

5.3 多个动画的使用实例
多个组件依次动画执行:

#include <QPushButton>
#include <QVBoxLayout>
#include <QPropertyAnimation>
#include <QSequentialAnimationGroup>MainWindow::MainWindow(QWidget *parent): QWidget(parent)
{this->setFixedSize(800, 600);this->setWindowTitle("动画");// 创建三个按钮QPushButton *btn1 = new QPushButton("Button 1", this);QPushButton *btn2 = new QPushButton("Button 2", this);QPushButton *btn3 = new QPushButton("Button 3", this);btn1->move(20, 50);btn2->move(20, 100);btn3->move(20, 150);// 创建动画组QSequentialAnimationGroup *group = new QSequentialAnimationGroup(this);// 按钮 1 动画QPropertyAnimation *anim1 = new QPropertyAnimation(btn1, "pos");anim1->setDuration(500);anim1->setEndValue(QPoint(250, 50));// 按钮 2 动画QPropertyAnimation *anim2 = new QPropertyAnimation(btn2, "pos");anim2->setDuration(500);anim2->setEndValue(QPoint(250, 100));// 按钮 3 动画QPropertyAnimation *anim3 = new QPropertyAnimation(btn3, "pos");anim3->setDuration(500);anim3->setEndValue(QPoint(250, 150));// 插入动画到顺序组group->addAnimation(anim1);group->addAnimation(anim2);group->addAnimation(anim3);// 点击任意按钮启动动画connect(btn1, &QPushButton::clicked, this, [=]{group->start();});connect(btn2, &QPushButton::clicked, this, [=]{group->start();});connect(btn3, &QPushButton::clicked, this, [=]{group->start();});
}

在这里插入图片描述

六、使用缓和曲线

  在 Qt 的动画系统中,缓和曲线(Easing Curve) 用于控制动画过程中属性值随时间的变化速度,也就是“动画节奏感”。这通过 QEasingCurve 类实现,可以让动画效果更自然、生动,比如:

  • 加速、减速(常见于 UI 移动)
  • 弹跳、回弹(常见于游戏 UI)
  • 弹性伸缩(拟物风格)

设置缓和曲线的方法:
每个 QPropertyAnimation 都可以通过如下方式设置缓和曲线:

QPropertyAnimation *anim = new QPropertyAnimation(widget, "pos");
anim->setDuration(1000);
anim->setStartValue(QPoint(0, 0));
anim->setEndValue(QPoint(200, 200));// 设置缓和曲线
anim->setEasingCurve(QEasingCurve::OutBounce);

常用缓和曲线类型:
在这里插入图片描述
示例:三种不同节奏的移动动画

#include <QPushButton>
#include <QPropertyAnimation>MainWindow::MainWindow(QWidget *parent): QWidget(parent)
{this->setFixedSize(800, 600);this->setWindowTitle("动画");QStringList labels = { "Linear", "OutBounce", "InOutBack" };for (int i = 0; i < 3; ++i) {QPushButton *btn = new QPushButton(labels[i], this);btn->move(20, 50 + i * 50);QPropertyAnimation *anim = new QPropertyAnimation(btn, "pos", this);anim->setDuration(1000);anim->setStartValue(QPoint(20, 50 + i * 50));anim->setEndValue(QPoint(250, 50 + i * 50));anim->setEasingCurve(QEasingCurve::OutBounce);anim->start(QAbstractAnimation::DeleteWhenStopped);}
}

此时运行程序会发现,它会使按钮部件就像从开始位置掉落到结束位置的皮球一样出现弹跳效果。

七、状态机框架

什么是状态机?
状态机(State Machine)是一种数学模型,用来表示对象的状态和状态之间的切换规则。在 Qt 中,状态机由以下核心元素组成:

  • QStateMachine:状态机管理器;
  • QState / QFinalState:状态;
  • QAbstractTransition:状态间的过渡;
  • QSignalTransition:基于信号的过渡;
  • QHistoryState:记住某个状态组最后进入的子状态(可用于“返回上次状态”);
  • QState::assignProperty():状态进入时自动设置对象属性(常用于动画或 UI 状态变化);

简单使用示例:
场景:点击按钮在红色和绿色之间切换

#include <QPushButton>
#include <QStateMachine>
#include <QState>
#include <QSignalTransition>MainWindow::MainWindow(QWidget *parent): QWidget(parent)
{this->setFixedSize(800, 600);this->setWindowTitle("动画");QPushButton* pBtn = new QPushButton("Toggle Color", this);QStateMachine *pMachine = new QStateMachine(this);QState *redState = new QState();redState->assignProperty(pBtn, "styleSheet", "background-color: red");QState *greenState = new QState();greenState->assignProperty(pBtn, "styleSheet", "background-color: green");// 状态切换redState->addTransition(pBtn, &QPushButton::clicked, greenState);greenState->addTransition(pBtn, &QPushButton::clicked, redState);// 添加状态并设置初始状态pMachine->addState(redState);pMachine->addState(greenState);pMachine->setInitialState(greenState);pMachine->start();
}

状态机和动画结合

结合状态机和动画的关键点:

  • 利用 QState::assignProperty() 设置状态进入时的属性值;
  • 使用 QStateMachine::addDefaultAnimation() 添加动画,动画会在状态切换时自动播放;
  • 动画可作用于多种属性(位置、大小、颜色、透明度等);
  • 结合定时器和事件可以实现更复杂动画状态切换。
#include <QPushButton>
#include <QStateMachine>
#include <QState>
#include <QPropertyAnimation>MainWindow::MainWindow(QWidget *parent): QWidget(parent)
{this->setFixedSize(800, 600);this->setWindowTitle("动画");QPushButton *pBtn = new QPushButton("Click me", this);pBtn->setGeometry(100, 100, 150, 50);pBtn->show();QStateMachine *pMachine = new QStateMachine(this);// 状态1:按钮红色,左上角QState *state1 = new QState();state1->assignProperty(pBtn, "geometry", QRect(100, 100, 150, 50));state1->assignProperty(pBtn, "styleSheet", "background-color: red");// 状态2:按钮绿色,右下角QState *state2 = new QState();state2->assignProperty(pBtn, "geometry", QRect(400, 300, 150, 100));state2->assignProperty(pBtn, "styleSheet", "background-color: green");// 状态切换state1->addTransition(pBtn, &QPushButton::clicked, state2);state2->addTransition(pBtn, &QPushButton::clicked, state1);pMachine->addState(state1);pMachine->addState(state2);pMachine->setInitialState(state1);// 添加动画,自动在状态切换时播放QPropertyAnimation *anim = new QPropertyAnimation(pBtn, "geometry");anim->setDuration(500);anim->setEasingCurve(QEasingCurve::InOutQuad);pMachine->addDefaultAnimation(anim);pMachine->start();
}

效果显示:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/bicheng/84443.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

IP选择注意事项

IP选择注意事项 MTP、FTP、EFUSE、EMEMORY选择时&#xff0c;需要考虑以下参数&#xff0c;然后确定后选择IP。 容量工作电压范围温度范围擦除、烧写速度/耗时读取所有bit的时间待机功耗擦写、烧写功耗面积所需要的mask layer

Flask RESTful 示例

目录 1. 环境准备2. 安装依赖3. 修改main.py4. 运行应用5. API使用示例获取所有任务获取单个任务创建新任务更新任务删除任务 中文乱码问题&#xff1a; 下面创建一个简单的Flask RESTful API示例。首先&#xff0c;我们需要创建环境&#xff0c;安装必要的依赖&#xff0c;然后…

filebeat原理架构

Filebeat 是基于 Golang 开发的轻量级日志采集 Agent&#xff0c;其核心架构设计围绕高效、可靠地采集与转发日志数据&#xff0c;主要组件和工作流程如下&#xff1a; ‌一、核心架构组件‌ ‌输入 (Inputs)‌ 负责监控指定的日志源&#xff08;如文件路径、日志文件&#x…

Air8000开发板新资料开放!多功能+高扩展特性全面解锁

Air8000开发板最新技术资料正式向开发者开放。这个开发板集多功能与高扩展性于一身&#xff0c;将为物联网、嵌入式系统等领域的创新项目提供更强大的技术支持&#xff0c;助力开发者快速实现创意落地。 工程师朋友们&#xff0c;Air8000开发板“多功能集成高扩展性”&#xff…

如何迁移Cordova应用到HarmonyOS 5 以及迁移时常见的问题?

以下是 Cordova 应用迁移至 HarmonyOS 5 的完整方案及常见问题解决方案&#xff0c;结合最新技术实践整理&#xff1a; 一、迁移流程 1. ‌方案选择‌ ‌方案‌‌适用场景‌‌操作复杂度‌‌Android 兼容层方案‌简单应用快速上线低&#xff08;无需修改代码&#xff09;‌原…

板凳-------Mysql cookbook学习 (十--4)

6.3 设置客户端时区 --客户端位于不同时区需要注意&#xff0c;如果位于同一时区则不需要关心 mysql> drop table if exists t; Query OK, 0 rows affected (0.06 sec)mysql> create table t (ts timestamp); Query OK, 0 rows affected (0.05 sec)mysql> insert int…

如何根据excel表生成sql的insert脚本

根据excel自带的vba宏进行操作 首先altF11 点击插入~模块 录取执行语句 Sub GenerateSQL()Dim lastRow As IntegerlastRow Cells(Rows.Count, 1).End(xlUp).RowFor i 2 To lastRow 假设第一行是标题Cells(i, "S").Value "INSERT INTO table_name (ID, RE…

React hook之useRef

React useRef 详解 useRef 是 React 提供的一个 Hook&#xff0c;用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途&#xff0c;下面我将全面详细地介绍它的特性和用法。 基本概念 1. 创建 ref const refContainer useRef(initialValue);initialValu…

开疆智能ModbusTCP转Canopen网关连接AB PLC与台达伺服通讯案例

本案例是罗克韦尔PLC通过开疆智能ModbusTCP转Canopen网关连接台达A2伺服的配置案例。 配置方法&#xff1a; 首先打开PLC配置软件“Studio5000”并新建项目导入通讯文件 对功能块进行设置 填写本地IP地址以及服务区IP地址以及寄存器 填写寄存器地址数量及使能 确认无误后将配置…

用 LoRA 对 Qwen2.5-VL 模型进行SFT - LoRA微调流程

用 LoRA 对 Qwen2.5-VL 模型进行SFT - LoRA微调流程 flyfish ┌──────────────────────────────────────────────────────────────────────────┐ │ 环境准备与启动 …

熵最小化Entropy Minimization (二): 案例实施

前面介绍了熵最小化、常用的权重函数汇总、半监督学习&#xff1a;低密度分离假设 (Low-Density Separation Assumption)、标签平滑、信息最大化等相关的知识点&#xff0c;本文采用一个MNIST10分类的数据集来进一步体会它们的效果。 案例实施 对比方法 纯监督学习方法&…

联邦学习聚合参数操作详解

联邦学习中常见的模型聚合操作&#xff0c;具体用于对来自多个客户端的模型更新进行聚合&#xff0c;以得到全局模型。在联邦学习框架下&#xff0c;多个客户端在本地训练各自的模型后&#xff0c;会将模型更新&#xff08;通常是模型的权重&#xff09;发送到中央服务器&#…

蓝牙 BLE 扫描面试题大全(2):进阶面试题与实战演练

前文覆盖了 BLE 扫描的基础概念与经典问题蓝牙 BLE 扫描面试题大全(1)&#xff1a;从基础到实战的深度解析-CSDN博客&#xff0c;但实际面试中&#xff0c;企业更关注候选人对复杂场景的应对能力&#xff08;如多设备并发扫描、低功耗与高发现率的平衡&#xff09;和前沿技术的…

基于Flask实现的医疗保险欺诈识别监测模型

基于Flask实现的医疗保险欺诈识别监测模型 项目截图 项目简介 社会医疗保险是国家通过立法形式强制实施&#xff0c;由雇主和个人按一定比例缴纳保险费&#xff0c;建立社会医疗保险基金&#xff0c;支付雇员医疗费用的一种医疗保险制度&#xff0c; 它是促进社会文明和进步的…

机房断电后 etcd 启动失败的排查与快速恢复实录

目录 机房断电后 etcd 启动失败的排查与快速恢复实录 背景与问题起因 报错分析 解决方案&#xff1a;删除 member 数据重新初始化 步骤 1&#xff1a;停止 etcd 容器或服务 步骤 2&#xff1a;删除 member 目录 步骤 3&#xff1a;重启 etcd 服务 附加提醒 总结与后续…

Linux上并行打包压缩工具

文章目录 Linux上并行打包压缩工具1. **Pigz (Parallel gzip)**2. **Pbzip2 (Parallel bzip2)**3. **Pixz (Parallel xz)**4. **Zstd (支持多线程)**5. **GNU Parallel 传统工具**6. **Fastest Tools (综合建议)**注意事项&#xff1a; tar和zstd多线程压缩和解压**1. 多线程压…

【K8S系列】K8S中Service 无法访问问题的深度分析

摘要 &#xff1a; 本文是关于 Kubernetes 中 Service 无法访问问题的深度分析&#xff0c;结合根本原因、诊断策略与解决方案的系统性指南&#xff1a; Kubernetes Service 访问故障全景解析&#xff1a;从底层机制到实战修复 Service 作为 Kubernetes 集群内网络通信的核心抽…

Leetcode 3577. Count the Number of Computer Unlocking Permutations

Leetcode 3577. Count the Number of Computer Unlocking Permutations 1. 解题思路2. 代码实现 题目链接&#xff1a;3577. Count the Number of Computer Unlocking Permutations 1. 解题思路 这一题其实就是一个脑筋急转弯&#xff0c;要想要能够将所有的电脑解锁&#x…

进行性核上性麻痹护理指南:全维度守护健康

进行性核上性麻痹是一种罕见的神经系统退行性疾病&#xff0c;会导致患者出现运动障碍、吞咽困难、认知障碍等症状。科学的健康护理对延缓病情发展、提升患者生活质量至关重要。 饮食护理&#xff1a;由于患者常存在吞咽困难&#xff0c;食物应选择糊状、软烂的类型&#xff0c…

【浅析赛题,国赛一等奖水平:思路+模型:】2025 年第八届河北省研究生数学建模竞赛:A 题 基于图论的复杂网络分析与可视化建模

问题一&#xff1a;社交网络拓扑结构分析与影响力评估 基础模型 有向加权图构建&#xff1a;将用户设为节点&#xff0c;互动关系为有向边&#xff0c;以互动频率&#xff08;如一定时间内点赞、评论、转发次数&#xff09;或加权求和&#xff08;赋予不同互动类型不同权重&a…