Qt动画功能学习

Qt动画功能学习

1. 项目概述

本项目展示了如何使用Qt的动画框架实现界面元素的动画效果,包括几何属性动画、颜色动画和不透明度动画。Qt提供了强大的动画系统,可以轻松实现各种UI元素的平滑过渡效果,提升用户体验。

1.1 项目结构

复制代码
48/
├── 48.pro          # 项目配置文件
├── main.cpp        # 主函数入口
├── widget.h        # Widget类头文件
├── widget.cpp      # Widget类实现文件
└── widget.ui       # 界面设计文件

1.2 功能特点

  • 几何属性动画:控制控件的位置和大小变化
  • 颜色动画:控制控件的颜色渐变效果
  • 不透明度动画:控制控件的透明度变化
  • 支持设置动画时长、循环次数和缓和曲线

2. 代码实现

2.1 项目配置文件 (48.pro)

qmake 复制代码
QT       += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

CONFIG += c++11

# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

SOURCES += \
    main.cpp \
    widget.cpp

HEADERS += \
    widget.h

FORMS += \
    widget.ui

# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

关键点说明:

  • 动画功能是Qt核心模块的一部分,不需要额外添加模块

2.2 主函数 (main.cpp)

cpp 复制代码
#include "widget.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();
    return a.exec();
}

2.3 Widget类头文件 (widget.h)

cpp 复制代码
#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QPropertyAnimation>  // 属性动画类

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

private slots:
    // 按钮点击事件处理函数
    void on_pushButton_clicked();    // 几何动画按钮
    void on_pushButton_2_clicked();  // 颜色动画按钮
    void on_pushButton_3_clicked();  // 不透明度动画按钮

private:
    Ui::Widget *ui;

    // 三种不同类型的属性动画对象
    QPropertyAnimation *propertyAnimation;   // 几何属性动画
    QPropertyAnimation *propertyAnimation1;  // 颜色动画
    QPropertyAnimation *propertyAnimation2;  // 不透明度动画
};
#endif // WIDGET_H

关键点说明:

  • #include <QPropertyAnimation> - 包含属性动画相关的头文件
  • 定义了三个 QPropertyAnimation 指针,分别用于不同类型的动画
  • 定义了三个槽函数,用于响应按钮点击事件

2.4 Widget类实现文件 (widget.cpp)

cpp 复制代码
#include "widget.h"
#include "ui_widget.h"
#include <QGraphicsColorizeEffect>  // 颜色效果
#include <QGraphicsOpacityEffect>   // 不透明度效果

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    // 1. 几何属性动画初始化
    propertyAnimation = new QPropertyAnimation(ui->geometryWidget, "geometry");

    // 设置动画起始值
    propertyAnimation->setStartValue(QRect(0, 0, 100, 100));
    // 设置某个时间段值(关键帧)
    propertyAnimation->setKeyValueAt(0.2, QRect(600, 0, 100, 100));
    // 设置结束值
    propertyAnimation->setEndValue(QRect(600, 400, 200, 200));
    // 设置动画时长(毫秒)
    propertyAnimation->setDuration(2000);
    // 设置动画循环周期(1表示播放一次,-1表示无限循环)
    propertyAnimation->setLoopCount(1);
    // 设置动画的缓和曲线(动画曲线)
    propertyAnimation->setEasingCurve(QEasingCurve::OutQuart);

    // 2. 颜色动画
    // 创建颜色效果对象
    QGraphicsColorizeEffect *graphicsColorizeEffect = new QGraphicsColorizeEffect(this);
    // 将效果应用到控件
    ui->colorWidget->setGraphicsEffect(graphicsColorizeEffect);
    // 创建属性动画,操作颜色效果的color属性
    propertyAnimation1 = new QPropertyAnimation(graphicsColorizeEffect, "color");
    // 设置起始颜色
    propertyAnimation1->setStartValue(QColor(Qt::yellow)); // 也可以使用 rgb(100, 100, 100)
    // 设置结束颜色
    propertyAnimation1->setEndValue(QColor(Qt::darkGray)); // 也可以使用 rgb(20, 20, 50)
    // 设置动画时长
    propertyAnimation1->setDuration(2000);

    // 3. 不透明度动画
    // 创建不透明度效果对象
    QGraphicsOpacityEffect *graphicsOpacityEffect = new QGraphicsOpacityEffect(this);
    // 将效果应用到控件
    ui->opacityWidget->setGraphicsEffect(graphicsOpacityEffect);
    // 创建属性动画,操作不透明度效果的opacity属性
    propertyAnimation2 = new QPropertyAnimation(graphicsOpacityEffect, "opacity");
    // 设置起始不透明度(0.0表示完全透明)
    propertyAnimation2->setStartValue(0.0);
    // 设置结束不透明度(1.0表示完全不透明)
    propertyAnimation2->setEndValue(1.0);
    // 设置动画时长
    propertyAnimation2->setDuration(5000);
}

Widget::~Widget()
{
    delete ui;
}

// 几何动画按钮点击事件
void Widget::on_pushButton_clicked()
{
    // 启动几何动画
    propertyAnimation->start();
}

// 颜色动画按钮点击事件
void Widget::on_pushButton_2_clicked()
{
    // 启动颜色动画
    propertyAnimation1->start();
}

// 不透明度动画按钮点击事件
void Widget::on_pushButton_3_clicked()
{
    // 启动不透明度动画
    propertyAnimation2->start();
}

关键点说明:

  1. 几何属性动画

    • 通过 QPropertyAnimation 控制控件的 geometry 属性
    • setStartValue 设置起始几何属性
    • setKeyValueAt 设置中间关键帧(0.2表示动画进行到20%的位置)
    • setEndValue 设置结束几何属性
    • setDuration 设置动画持续时间(毫秒)
    • setLoopCount 设置循环次数
    • setEasingCurve 设置缓和曲线,控制动画的速度变化
  2. 颜色动画

    • 使用 QGraphicsColorizeEffect 创建颜色效果
    • 将效果应用到控件 setGraphicsEffect
    • 创建属性动画控制效果的 color 属性
    • 设置起始颜色和结束颜色
  3. 不透明度动画

    • 使用 QGraphicsOpacityEffect 创建不透明度效果
    • 将效果应用到控件
    • 创建属性动画控制效果的 opacity 属性
    • 设置起始不透明度(0.0)和结束不透明度(1.0)
  4. 动画启动

    • 通过 start() 方法启动动画

2.5 界面设计文件 (widget.ui)

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>Widget</class>
 <widget class="QWidget" name="Widget">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>800</width>
    <height>600</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>Widget</string>
  </property>
  <widget class="QWidget" name="geometryWidget" native="true">
   <property name="geometry">
    <rect>
     <x>180</x>
     <y>70</y>
     <width>120</width>
     <height>80</height>
    </rect>
   </property>
   <property name="styleSheet">
    <string notr="true">QWidget { background-color: rgb(239, 41, 41); }
</string>
   </property>
  </widget>
  <widget class="QWidget" name="colorWidget" native="true">
   <property name="geometry">
    <rect>
     <x>180</x>
     <y>170</y>
     <width>120</width>
     <height>80</height>
    </rect>
   </property>
   <property name="styleSheet">
    <string notr="true">QWidget { background-color: blue }
</string>
   </property>
  </widget>
  <widget class="QWidget" name="opacityWidget" native="true">
   <property name="geometry">
    <rect>
     <x>180</x>
     <y>280</y>
     <width>120</width>
     <height>80</height>
    </rect>
   </property>
   <property name="styleSheet">
    <string notr="true">QWidget { background-color: yellow }
</string>
   </property>
  </widget>
  <widget class="QWidget" name="">
   <property name="geometry">
    <rect>
     <x>660</x>
     <y>100</y>
     <width>115</width>
     <height>301</height>
    </rect>
   </property>
   <layout class="QVBoxLayout" name="verticalLayout">
    <item>
     <widget class="QPushButton" name="pushButton">
      <property name="text">
       <string>几何动画</string>
      </property>
     </widget>
    </item>
    <item>
     <widget class="QPushButton" name="pushButton_2">
      <property name="text">
       <string>颜色动画</string>
      </property>
     </widget>
    </item>
    <item>
     <widget class="QPushButton" name="pushButton_3">
      <property name="text">
       <string>不透明度动画</string>
      </property>
     </widget>
    </item>
   </layout>
  </widget>
 </widget>
 <resources/>
 <connections/>
</ui>

关键点说明:

  • 界面包含三个自定义控件(QWidget)用于显示动画效果:
    • geometryWidget:用于几何动画,背景色为红色
    • colorWidget:用于颜色动画,背景色为蓝色
    • opacityWidget:用于不透明度动画,背景色为黄色
  • 右侧有三个按钮,用于触发不同类型的动画

3. Qt动画框架详解

3.1 动画类型

类名 描述 用途
QPropertyAnimation 属性动画 动画化Qt对象的属性变化
QVariantAnimation 变体动画 QPropertyAnimation的基类,提供变体值之间的插值
QPauseAnimation 暂停动画 提供暂停功能
QSequentialAnimationGroup 顺序动画组 按顺序播放一组动画
QParallelAnimationGroup 并行动画组 同时播放一组动画
QAnimationGroup 动画组 所有动画组的基类

3.2 图形效果类型

类名 描述 用途
QGraphicsEffect 图形效果基类 所有图形效果的基类
QGraphicsBlurEffect 模糊效果 为控件添加模糊效果
QGraphicsColorizeEffect 颜色效果 为控件添加颜色效果
QGraphicsDropShadowEffect 阴影效果 为控件添加阴影效果
QGraphicsOpacityEffect 不透明度效果 控制控件的不透明度

3.3 缓和曲线类型

Qt提供了多种缓和曲线(QEasingCurve),用于控制动画的速度变化:

曲线类型 描述
Linear 线性变化,匀速动画
InQuad, OutQuad, InOutQuad 二次方缓动
InCubic, OutCubic, InOutCubic 三次方缓动
InQuart, OutQuart, InOutQuart 四次方缓动
InQuint, OutQuint, InOutQuint 五次方缓动
InSine, OutSine, InOutSine 正弦缓动
InExpo, OutExpo, InOutExpo 指数缓动
InCirc, OutCirc, InOutCirc 圆形缓动
InElastic, OutElastic, InOutElastic 弹性缓动
InBack, OutBack, InOutBack 回弹缓动
InBounce, OutBounce, InOutBounce 弹跳缓动

4. 实现步骤详解

4.1 创建属性动画

cpp 复制代码
// 创建属性动画对象
QPropertyAnimation *animation = new QPropertyAnimation(targetObject, "propertyName");

// 设置动画参数
animation->setStartValue(startValue);  // 起始值
animation->setEndValue(endValue);      // 结束值
animation->setDuration(duration);      // 持续时间(毫秒)
animation->setLoopCount(loopCount);    // 循环次数
animation->setEasingCurve(easingCurve); // 缓和曲线

// 启动动画
animation->start();

4.2 创建关键帧动画

cpp 复制代码
// 创建属性动画对象
QPropertyAnimation *animation = new QPropertyAnimation(targetObject, "propertyName");

// 设置动画参数
animation->setStartValue(startValue);  // 起始值
animation->setKeyValueAt(0.25, value1); // 25%位置的值
animation->setKeyValueAt(0.5, value2);  // 50%位置的值
animation->setKeyValueAt(0.75, value3); // 75%位置的值
animation->setEndValue(endValue);      // 结束值
animation->setDuration(duration);      // 持续时间(毫秒)

// 启动动画
animation->start();

4.3 创建图形效果

cpp 复制代码
// 创建图形效果
QGraphicsEffect *effect = new QGraphicsXXXEffect(parent);

// 配置效果参数
// ...

// 应用效果到控件
widget->setGraphicsEffect(effect);

// 创建动画控制效果属性
QPropertyAnimation *animation = new QPropertyAnimation(effect, "propertyName");
// ...

4.4 创建动画组

cpp 复制代码
// 创建顺序动画组
QSequentialAnimationGroup *sequentialGroup = new QSequentialAnimationGroup();

// 添加子动画
sequentialGroup->addAnimation(animation1);
sequentialGroup->addAnimation(animation2);
sequentialGroup->addAnimation(animation3);

// 启动动画组
sequentialGroup->start();

// 创建并行动画组
QParallelAnimationGroup *parallelGroup = new QParallelAnimationGroup();

// 添加子动画
parallelGroup->addAnimation(animation1);
parallelGroup->addAnimation(animation2);
parallelGroup->addAnimation(animation3);

// 启动动画组
parallelGroup->start();

5. 常用功能示例

5.1 控制动画状态

cpp 复制代码
// 启动动画
animation->start();

// 暂停动画
animation->pause();

// 恢复动画
animation->resume();

// 停止动画
animation->stop();

// 设置当前时间
animation->setCurrentTime(msecs);

5.2 动画事件处理

cpp 复制代码
// 连接动画信号
connect(animation, &QPropertyAnimation::finished, this, &MyClass::onAnimationFinished);
connect(animation, &QPropertyAnimation::stateChanged, this, &MyClass::onStateChanged);
connect(animation, &QPropertyAnimation::currentLoopChanged, this, &MyClass::onLoopChanged);

// 事件处理函数
void MyClass::onAnimationFinished()
{
    qDebug() << "Animation finished";
    // 处理动画完成事件
}

void MyClass::onStateChanged(QAbstractAnimation::State newState, QAbstractAnimation::State oldState)
{
    qDebug() << "State changed from" << oldState << "to" << newState;
    // 处理状态变化事件
}

void MyClass::onLoopChanged(int currentLoop)
{
    qDebug() << "Current loop:" << currentLoop;
    // 处理循环变化事件
}

5.3 自定义动画属性

对于没有内置动画属性的对象,可以使用Q_PROPERTY宏定义自定义属性:

cpp 复制代码
class MyObject : public QObject
{
    Q_OBJECT
    Q_PROPERTY(float customValue READ customValue WRITE setCustomValue)

public:
    MyObject(QObject *parent = nullptr) : QObject(parent), m_customValue(0.0) {}

    float customValue() const { return m_customValue; }
    void setCustomValue(float value) {
        if (m_customValue != value) {
            m_customValue = value;
            update(); // 触发更新
        }
    }

private:
    float m_customValue;
};

// 使用自定义属性创建动画
MyObject *obj = new MyObject(this);
QPropertyAnimation *animation = new QPropertyAnimation(obj, "customValue");
animation->setStartValue(0.0);
animation->setEndValue(1.0);
animation->setDuration(1000);
animation->start();

7.1 状态机动画

Qt提供了状态机框架,可以与动画系统结合使用:

cpp 复制代码
#include <QStateMachine>
#include <QState>
#include <QPropertyAnimation>

// 创建状态机
QStateMachine *machine = new QStateMachine(this);

// 创建状态
QState *state1 = new QState(machine);
QState *state2 = new QState(machine);

// 设置状态的属性值
state1->assignProperty(widget, "geometry", QRect(0, 0, 100, 100));
state2->assignProperty(widget, "geometry", QRect(200, 200, 200, 200));

// 添加状态转换
state1->addTransition(button, &QPushButton::clicked, state2);
state2->addTransition(button, &QPushButton::clicked, state1);

// 设置动画
QPropertyAnimation *animation = new QPropertyAnimation(widget, "geometry");
animation->setDuration(1000);

// 将动画添加到状态机
machine->addDefaultAnimation(animation);

// 设置初始状态并启动状态机
machine->setInitialState(state1);
machine->start();

7.2 动画与样式表结合

cpp 复制代码
// 创建动画控制样式表属性
QPropertyAnimation *animation = new QPropertyAnimation(widget, "styleSheet");

// 设置样式表变化
animation->setStartValue("background-color: red;");
animation->setEndValue("background-color: blue;");
animation->setDuration(1000);

// 启动动画
animation->start();

7.3 动画与图形视图框架结合

cpp 复制代码
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QGraphicsRectItem>
#include <QPropertyAnimation>

// 创建场景和视图
QGraphicsScene *scene = new QGraphicsScene(this);
QGraphicsView *view = new QGraphicsView(scene, this);

// 创建图形项
QGraphicsRectItem *rect = new QGraphicsRectItem(0, 0, 100, 100);
rect->setBrush(QBrush(Qt::red));
scene->addItem(rect);

// 创建动画
QPropertyAnimation *animation = new QPropertyAnimation(rect, "pos");
animation->setStartValue(QPointF(0, 0));
animation->setEndValue(QPointF(200, 200));
animation->setDuration(2000);
animation->setLoopCount(-1); // 无限循环

// 启动动画
animation->start();
相关推荐
淮北4944 小时前
计算机网络学习(七、网络安全)
学习·计算机网络·web安全
福大大架构师每日一题4 小时前
go 1.25.1发布:重点修复net/http跨域保护安全漏洞(CVE-2025-47910)
开发语言·http·golang
Ophelia(秃头版4 小时前
经典设计模式:单例模式、工厂模式
java·开发语言·单例模式
萘柰奈4 小时前
Unity学习----【进阶】Input System学习(一)--导入与基础的设备调用API
学习
天天开心a4 小时前
OSPF基础部分知识点
网络·笔记·学习·智能路由器·hcip
Dear.爬虫5 小时前
Golang中逃逸现象, 变量“何时栈?何时堆?”
开发语言·后端·golang
淮北4945 小时前
计算机网络学习(六、应用层)
linux·学习·计算机网络
编码浪子5 小时前
趣味学RUST基础篇(构建一个命令行程序2重构)
开发语言·重构·rust
echoarts6 小时前
MATLAB R2025a安装配置及使用教程(超详细保姆级教程)
开发语言·其他·matlab