我们先看效果:
点开“开始”:蝴蝶的透明度从0.5逐渐增加到1,然后又从1逐渐减少到0.5,这样不断循环变化。
点击“结束”按钮,动画停止。
其实这个用属性动画QPropertyAnimation和串行动画组QSequentialAnimationGroup,以及Q_PROPERTY,一起来做,非常简单。
首先我们需要一个变量,来存储图片的透明度:
double m_imageOpacity;
需要它的get和set方法
写法一:
Q_PROPERTY(double imageOpacity READ imageOpacity WRITE setImageOpacity)
private:
double imageOpacity() const
{
return m_imageOpacity;
}
void setImageOpacity(double value)
{
m_imageOpacity = value;
}
private:
double m_imageOpacity;
写法二:
Q_PROPERTY(double imageOpacity MEMBER m_imageOpacity)
private:
double m_imageOpacity;
两种写法等效,这里我们用写法二。
新建一个基于QWidget的工程
全家福
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class QSequentialAnimationGroup;
class QPropertyAnimation;
class Widget : public QWidget
{
Q_OBJECT
Q_PROPERTY(double imageOpacity MEMBER m_imageOpacity)
public:
Widget(QWidget *parent = nullptr);
~Widget() override;
protected:
void paintEvent(QPaintEvent *event) override;
private:
Ui::Widget *ui;
double m_imageOpacity;
QPixmap m_pixmap;
QSequentialAnimationGroup *m_sequentialGroup;
QPropertyAnimation *m_fadeInAnimation; //淡入动画,透明度增加
QPropertyAnimation *m_fadeOutAnimation; //淡出动画,也就是透明度逐渐减少
};
#endif // WIDGET_H
widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include <QSequentialAnimationGroup>
#include <QPropertyAnimation>
#include <QPainter>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
, m_imageOpacity(0.5)
, m_pixmap(":/images/butterfly.png")
, m_sequentialGroup(nullptr)
, m_fadeInAnimation(nullptr)
, m_fadeOutAnimation(nullptr)
{
ui->setupUi(this);
//以下是设置变色动画
m_sequentialGroup = new QSequentialAnimationGroup(this); //序列动画组,为的是让m_fadeInAnimation动画先播,再播m_fadeOutAnimation
m_fadeInAnimation = new QPropertyAnimation(this, "imageOpacity"); //这个和Q_PROPERTY中的对应起来
m_fadeInAnimation->setStartValue(0.5); //设置属性的初值
m_fadeInAnimation->setEndValue(1); //设置属性的结束值
m_fadeInAnimation->setEasingCurve(QEasingCurve::InCubic); //设置动画曲线
m_fadeInAnimation->setDuration(2000); //设置持续时间,单位是millisecond
m_fadeOutAnimation = new QPropertyAnimation(this, "imageOpacity");
m_fadeOutAnimation->setStartValue(1);
m_fadeOutAnimation->setEndValue(0.5);
m_fadeOutAnimation->setEasingCurve(QEasingCurve::InCubic);
m_fadeOutAnimation->setDuration(2000);
m_sequentialGroup->addAnimation(m_fadeInAnimation);
m_sequentialGroup->addAnimation(m_fadeOutAnimation);
m_sequentialGroup->setLoopCount(-1); //-1表示不断循环动画
connect(m_fadeInAnimation, &QPropertyAnimation::valueChanged, [=](){
this->update(); //属性发送变化的时候,update,重绘
});
connect(m_fadeOutAnimation, &QPropertyAnimation::valueChanged, [=](){
this->update(); //属性发送变化的时候,update,重绘
});
connect(ui->startPushButton, &QPushButton::clicked, [=](){
m_sequentialGroup->start(); //开始动画
});
connect(ui->stopPushButton, &QPushButton::clicked, [=](){
m_sequentialGroup->stop(); //结束动画
});
}
Widget::~Widget()
{
delete ui;
}
void Widget::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event)
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing, true); //开启抗锯齿
QRect target(60, 20, 200, 200);
painter.setOpacity(m_imageOpacity); //设置透明度
painter.drawPixmap(target, m_pixmap);
}
蝴蝶图片:
参考:
Qt 之 QPropertyAnimation