Qt动画的简单使用(QPropertyAnimation,含源码和注释)

一、Qt动画示例图(移动、缩放、不透明度)

下图为使用不同属性实现的效果,源码在本文第四节(源码含详细注释)。
在这里插入图片描述

二、什么是Qt动画

QPropertyAnimation是Qt自带的动画类,该类可以实现简单的控件动画效果,比如对控件的移动、缩放、不透明度这些来做动画效果(使用某效果之前需要使用setPropertyName函数指定需要的动画属性名,以下三个是Qt已经定义好的)。

  1. 移动(pos):主要实现移动效果,如从某个点移动到另一个点,所使用的变量类型为QPoint等。
  2. 缩放(geometry):可实现缩放和移动效果,该属性可以实现指定控件的缩放,并且在缩放的基础上还能实现移动。
  3. 不透明度(windowOpacity):实现控件的透明度设置(不过该属性只能对顶级窗口使用,对普通控件这些无效)。

三、遇到的问题

  1. QPropertyAnimation::setPropertyName: you can’t change the property name of a running animation
    该情况是在改变正在使用的动画属性。有可能是在使用某动画时(动画时间未结束时),再次调用该效果;如本文中使用的动画,当动画正在播放时多次点击按钮时出现。

  2. QPropertyAnimation: you’re trying to animate a non-existing property windsowOpacity of your QObject
    该情况为使用了不存在的动画属性名。这种情况需要修改动画属性名或自定义属性名(自定义属性名可以先了解Q_PROPERTY)

  3. QPropertyAnimation::updateState (动画属性名): Changing state of an animation without target
    该情况为没有指定动画的使用对象,使用setTargetObject函数设置使用对象即可

  4. 使用QPropertyAnimation最好不要使用局部变量,运行完后局部变量直接释放,动画就会没效果

四、源码

CMainWindow.h

#ifndef CMAINWINDOW_H
#define CMAINWINDOW_H

#include <QMainWindow>
#include <QPropertyAnimation>

namespace Ui {
class CMainWindow;
}

class CMainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit CMainWindow(QWidget *parent = 0);
    ~CMainWindow();

private slots:

    void on_posMoveBtn_clicked();   //pos

    void on_rectMoveBtn_clicked();  //geometry

    void on_opacityAnimationBtn_clicked();  //opacity

private:
    Ui::CMainWindow *ui;

    QPropertyAnimation *m_animation;        //动画对象指针
};

#endif // CMAINWINDOW_H

CMainWindow.cpp

#include "CMainWindow.h"
#include "ui_CMainWindow.h"

CMainWindow::CMainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::CMainWindow)
{
    ui->setupUi(this);
    //创建动画对象空间(初始化可以指定动画控件和动画需使用的动画属性名)
    m_animation = new QPropertyAnimation();
    m_animation->setTargetObject(ui->label);    //设置使用动画的控件
    m_animation->setEasingCurve(QEasingCurve::Linear); //设置动画效果
    //!统一的效果可以在对象创建的位置设置(如动画属性名、动画时间、动画使用对象等)
    //! 不同的设置在使用位置单独设置即可
}

CMainWindow::~CMainWindow()
{
    delete m_animation;
    delete ui;
}

void CMainWindow::on_posMoveBtn_clicked()
{
    //pos:按点移动的动画(移动)
    m_animation->setPropertyName("pos");    //指定动画属性名
    m_animation->setDuration(3000);    //设置动画时间(单位:毫秒)
    m_animation->setStartValue(ui->label->pos());  //设置动画起始位置在label控件当前的pos
    m_animation->setEndValue(ui->label->pos() + QPoint(200, 100)); //设置动画结束位置
    m_animation->start();   //启动动画
}

void CMainWindow::on_rectMoveBtn_clicked()
{
    //geometry:按矩形的动画(移动和缩放)
    m_animation->setPropertyName("geometry");   //指定动画属性名
    m_animation->setDuration(3000);    //设置动画时间(单位:毫秒)
    m_animation->setStartValue(ui->label->rect());  //设置动画起始位置

    //获取控件初始的大小
    int width = ui->label->rect().width();
    int height = ui->label->rect().height();

    //设置动画步长值,以及在该位置时的长宽
    m_animation->setKeyValueAt(0.5, QRect(ui->label->pos() - QPoint(100, 50)
                                  ,QSize( width + 50, height + 35)));

    m_animation->setEndValue(QRect(ui->label->pos() - QPoint(100, 50)
                             ,QSize( width, height))); //设置动画结束位置及其大小
    m_animation->start();   //启动动画
}

void CMainWindow::on_opacityAnimationBtn_clicked()
{
    //windowOpacity:不透明度(注意该效果只对顶级窗口有效哦)
    m_animation->setTargetObject(this);     //重设动画使用对象
    m_animation->setPropertyName("windowOpacity");  //指定动画属性名
    m_animation->setDuration(2000);     //设置动画时间(单位:毫秒)

    //设置动画步长值,以及在该位置时显示的透明度
    m_animation->setKeyValueAt(0, 1);
    m_animation->setKeyValueAt(0.5, 0);
    m_animation->setKeyValueAt(1, 0);

    m_animation->setLoopCount(-1);  //当值为-1时,动画一直运行,直到窗口关闭
    m_animation->start();   //启动动画
}

总结

当项目需要实现滑动进入或者循环缩放效果时可以使用QPropertyAnimation类,不过windowOpacity仅限顶级窗口使用,因此某控件单独的不透明度设置需要自定义

相关文档

Qt设置指定控件的不透明度(QPropertyAnimation + 自定义属性实现,含源码和注释)

友情提示——哪里看不懂可私哦,让我们一起互相进步吧
(创作不易,请留下一个免费的赞叭 谢谢 ^o^/)

注:文章为作者编程过程中所遇到的问题和总结,内容仅供参考,若有错误欢迎指出。
注:如有侵权,请联系作者删除

  • 46
    点赞
  • 152
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 11
    评论
### 回答1: Qt 是一个跨平台的 C++ 库,用于创建图形用户界面和应用程序。Qt 提供了丰富的功能和工具,以简化图形界面的开发过程。 在 Qt 中,可以使用多线程来实现动画启动界面。多线程能够将界面的渲染和逻辑处理分离,提高程序的响应性和用户体验。 首先,需要在主线程中创建一个启动界面的窗口,并设置该窗口为应用程序的主窗口,使其在程序启动时显示。在启动界面窗口中,可以添加一张图片或者一个动画控件,来展示用户需要的信息或者动画效果。 然后,在主线程中创建一个子线程,并在该子线程中执行后台任务和动画的逻辑处理。可以使用 QtQThread 类来创建和管理子线程。 在子线程中,可以使用 QTimer 控件来定时更新动画效果,并使用 QObject::moveToThread() 函数将动画控件或者需要更新的界面元素移动到子线程中进行渲染。 同时,需要保证子线程能够与主线程进行通信,以便在后台任务完成或动画效果更新时及时更新界面。可以使用 Qt 的信号和槽机制来进行线程间的通信。 最后,在主线程中,等待后台任务完成的信号,并在接收到信号后关闭启动界面窗口,显示应用程序的主窗口。 通过以上步骤,就可以实现一个使用多线程的启动界面动画。这样可以提高程序的响应速度,使用户在启动过程中能够看到动画效果,提升用户体验。同时,由于界面渲染和逻辑处理在不同线程中进行,可以减少界面卡顿的情况,保证程序的流畅性。 ### 回答2: 在Qt中,我们可以使用多线程来实现动画启动界面。下面是一个简单的示例: 首先,我们需要创建一个继承自QThread的自定义线程类。在这个线程类中,我们可以定义我们想要的动画效果。例如,可以使用QPropertyAnimation来实现一个渐变的启动界面动画。 接下来,在主线程中,我们可以通过创建一个实例化的自定义线程类对象。然后,我们可以将该线程对象启动,并在主线程中显示我们的启动界面。 下面是一个简单的示例代码: ```cpp #include <QApplication> #include <QMainWindow> #include <QThread> #include <QPropertyAnimation> class AnimationThread : public QThread { public: void run() override { // 创建一个QPropertyAnimation对象,设置动画效果 QPropertyAnimation animation; animation.setTargetObject(/* 设置动画目标对象,可以是QWidget或其他可动画化的对象 */); animation.setPropertyName(/* 设置动画属性,例如透明度 */); animation.setStartValue(/* 设置起始值 */); animation.setEndValue(/* 设置结束值 */); animation.setDuration(/* 设置动画时长 */); // 启动动画 animation.start(); // 等待动画结束 animation.wait(); } }; int main(int argc, char *argv[]) { QApplication a(argc, argv); QMainWindow mainWindow; mainWindow.show(); // 创建并启动动画线程 AnimationThread animationThread; animationThread.start(); // 显示启动界面,并等待动画线程结束 // 在动画线程结束后关闭启动界面 // ... return a.exec(); } ``` 需要注意的是,在实际的应用中,我们可能需要在动画线程结束后关闭启动界面,并继续执行其他任务。这需要根据具体的需求进行调整。 希望以上的回答能对您有所帮助! ### 回答3: Qt动画启动界面是通过多线程实现的。在启动界面中,主线程负责界面的初始化和显示,而动画效果则通过子线程来实现。 首先,主线程会负责创建启动界面的窗口,并设置窗口的初始属性和界面布局。然后,子线程被创建并启动,其中包动画的实现代码。 在子线程中,通常使用Qt动画框架来实现动画效果。可以使用QPropertyAnimation类来控制对象的属性变化,并通过设置动画的起始值和结束值来实现动画效果的过渡。另外,也可以使用QSequentialAnimationGroup或QParallelAnimationGroup来管理多个动画的协同播放。 子线程中的动画会在启动界面显示之前就开始播放。在动画播放过程中,主线程会不断更新界面,以实时显示动画的效果。 同时,为了确保动画的流畅播放,需要注意线程之间的同步与通信。可以使用Qt的信号与槽机制,通过在子线程中发送信号,再在主线程中接收信号,并根据信号内容来更新界面。 总而言之,Qt动画启动界面通过多线程的方式实现,主线程负责界面的初始化和显示,子线程负责动画的实现,通过信号与槽机制来实现线程之间的同步与通信,以实现流畅的动画效果。
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lw向北.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值