引言
动画很让人烦恼,在Qt中,已经给出了很多简单的动画,例如 QPropertyAnimation 类实现的动画,但是还不够智能,不是我想要的,相信你也有同感,今天我们就来实现自定义动画类
来方便我们日后的开发。
版权所有:瓯裔,转载请注明出处:http://blog.csdn.net/csnd_ayo
简介
操作系统:window7 x64
编程IDE:Qt Creator 4.2.1
Qt版本: 5.0.3 · 5.3.0 · 5.8.0
最后更新:2017年4月14日
示例
效果
-
封装后引用
封装后我只需要五行代码即可显示自定义的动画了。
#include "widget.h"
#include "ui_widget.h"
#include "customdynamicwidget.h"
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
dynamicAnima_ = new CustomDynamicWidget(this);
dynamicAnima_->setAnimation(QPixmap(":/q/level_num.png"),10,100);
dynamicAnima_->setGeometry(41,41,41,41);
dynamicAnima_->show();
dynamicAnima_->startClockwise();
}
Widget::~Widget()
{
delete ui;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
下载
拥有了这个类,你就拥有了所有动画!
代码:下载
图片:下载
原理
#include <QTimer>
#include <QPainter>
#include <QWidget>
-
逻辑流程
-
等比例切割传入的图片元素
-
利用了定时器(QTimer)
定时更新界面
- 定时器被触发
- 辨别当前帧
- 若是尾帧辨别是否启用了动画无限循环
- 修改帧
- 更新界面
-
重写paintEvent函数,利用画家类(QPainter)
完成自绘。
实现
逻辑函数
void CustomDynamicWidget::setAnimation(const QPixmap &_pix, const short _count, const int _msec) {
count_ = _count;
currentIndex_ = 0;
if (!pixList_.empty()) {
pixList_.clear();
}
else {
clockTimer_ = new QTimer(this);
clockTimer_->setInterval(_msec);
connect(clockTimer_, SIGNAL(timeout()), this, SLOT(updateClockwise()));
counterclockTimer_ = new QTimer(this);
counterclockTimer_->setInterval(_msec);
connect(counterclockTimer_, SIGNAL(timeout()), this, SLOT(updateCounterclockwise()));
}
for(short i=0; i != _count; ++i) {
pixList_.append(_pix.copy(i * (_pix.width() / _count), 0,
_pix.width() / _count, _pix.height()));
}
currentPix_ = pixList_.at(0);
this->setGeometry(0,0,currentPix_.width(),currentPix_.height());
update();
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
void CustomDynamicWidget::updateClockwise(void) {
do {
if (currentIndex_ < count_ && currentIndex_ >= 0) {
currentPix_ = pixList_.at(currentIndex_);
update();
if (currentIndex_ >= (count_ - 1)) {
if(isLoop_) {
currentIndex_ = 0;
return;
}
break;
}
++currentIndex_;
return;
}
#ifndef QT_NO_DEBUG
else {
qDebug() << __FUNCTION__ << "waring: 错误的下标" << currentIndex_;
}
#endif
} while(false);
clockTimer_->stop();
currentIndex_ = 0;
emit clockwiseFinished();
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 3、重写paintEvent函数,利用
画家类(QPainter)
完成自绘。
void CustomDynamicWidget::paintEvent(QPaintEvent *) {
QPainter painter(this);
painter.drawPixmap(rect(), currentPix_);
}
#ifndef CUSTOMDYNAMICWIDGET_H
#define CUSTOMDYNAMICWIDGET_H
#include <QWidget>
class QTimer;
class CustomDynamicWidget : public QWidget
{
Q_OBJECT
public:
explicit CustomDynamicWidget(QWidget *parent = 0);
void setAnimation(const QPixmap& _pix, const short _count = 8, const int _msec = 100);
void startClockwise(void);
void startCounterclockwise(void);
void stop(void);
void setLoop(const bool _isLoop = false) { isLoop_ = _isLoop; }
signals:
void clockwiseFinished(void);
void counterclockwiseFinished(void);
private slots:
/* 顺时针动画槽 */
void updateClockwise(void);
void updateCounterclockwise(void);
protected:
void paintEvent(QPaintEvent *);
private:
/* 动画(是否无限循环) */
bool isLoop_;
short count_;
short currentIndex_;
QTimer *clockTimer_;
QTimer *counterclockTimer_;
QPixmap currentPix_;
QList<QPixmap> pixList_;
};
#endif // CUSTOMDYNAMICWIDGET_H
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95