动画很让人烦恼,在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;
}
拥有了这个类,你就拥有了所有动画!
代码:下载
图片:下载
#include
#include
#include
逻辑流程
等比例切割传入的图片元素
利用了定时器(QTimer)
定时更新界面
重写paintEvent函数,利用画家类(QPainter)
完成自绘。
/*
* 设置动画
* setAnimation
* _pix:图片
* _count:图片帧数
* _msec:切换速度 (毫秒 1秒 = 1000毫秒)
*/
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();
}
定时器(QTimer)
定时更新界面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();
}
画家类(QPainter)
完成自绘。void CustomDynamicWidget::paintEvent(QPaintEvent *) {
QPainter painter(this);
painter.drawPixmap(rect(), currentPix_);
}
#ifndef CUSTOMDYNAMICWIDGET_H
#define CUSTOMDYNAMICWIDGET_H
/*
* 自定义动画类
* 作者:瓯裔
* 邮箱:[email protected]
* CSDN:http://blog.csdn.net/csnd_ayo
* 创建时间:2017年1月9日 19:34:13
* QT版本:5.0.2 ~ 5.8.0
*/
#include
/*
* 说明:
* 当前类是针对一张链式图片
* 链式图片默认为8帧,默认0.1秒播放一帧
* 可以根据自己需要进行设置与更改
* 进行自动切割,循环播放每一帧
*
* 示例:
* 类内声明 CustomDynamicWidget* dynamicAnima_
* ui->setupUi(this);
* dynamicAnima_ = new CustomDynamicWidget(this);
* dynamicAnima_->setAnimation(QPixmap(":/res/loading.png"),8,100);
* dynamicAnima_->setGeometry(100,100,300,300);
* dynamicAnima_->show();
* // 顺时针播放每帧
* dynamicAnima_->startClockwise();
*/
class QTimer;
class CustomDynamicWidget : public QWidget
{
Q_OBJECT
public:
explicit CustomDynamicWidget(QWidget *parent = 0);
/*
* 设置动画图标
* 函数名:setAnimation
* 参数 _pix:图标实例
* 参数 _count:图标实例动画帧数
* 参数 _msec:动画切帧速度 (毫秒级)
*/
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 pixList_;
};
#endif // CUSTOMDYNAMICWIDGET_H