在网上看到一个自定义的动画按钮很喜欢,大部分代码都是参考该博客,于是这里也学着设计了一个继承自QWidget的派生类AnimationButton。
大概思路就是重载基类QWidget里的事件(enterEvent、leaveEvent、paintEvent、mousePressEvent、mouseReleaseEvent),让鼠标进入和离开该派生类的时候能产生动画,并为其添加鼠标单击事件。
//animationbutton.h
#ifndef ANIMATIONBUTTON_H
#define ANIMATIONBUTTON_H
/*
* Writer:sym
* FileName:Animationbutton
* Date:2019-8-19
* */
#include <QtCore>
#include <QtGui>
#include <QObject>
#include <QWidget>
#include <QStackedWidget>
#include <qpainter.h>
#include <qpropertyanimation.h>
#include <qdebug.h>
class Animationbutton : public QWidget
{
Q_OBJECT
public:
explicit Animationbutton(QWidget *parent = nullptr);
~Animationbutton();
protected:
void enterEvent(QEvent *);
void leaveEvent(QEvent *);
void paintEvent(QPaintEvent *);
void mousePressEvent(QMouseEvent *e);
void mouseReleaseEvent(QMouseEvent *e);
private:
bool enter; //是否进入
bool leave; //是否离开
int pixWidth; //图片高度
int pixHeight; //图片宽度
int oldWidth; //图片原高度
int oldHeight; //图片旧高度
QPropertyAnimation *enterAnimation; //进入动画
QPropertyAnimation *leaveAnimation; //离开动画
int targetWidth; //目标动画宽度
int targetHeight; //目标动画高度
QString text; //显示文字
QString image; //图像路径
QPoint mousePos;
QStackedWidget *sWidget=0;
int curi;
signals:
//鼠标单击信号
void clicked();
private slots:
//进入动画
void enterImageChanged(QVariant index);
//离开动画
void leaveImageChanged(QVariant index);
//鼠标单击槽
void mouseClicked();
public slots:
//设置动画按钮文字
void setText(QString text);
//设置动画按钮图片
void setImage(QString image);
//设置stackwidgets
void setStackedWidgets(QStackedWidget *stackedWidget,int i);
//设置堆栈窗体当前页
void setCurrentWidget();
};
#endif // ANIMATIONBUTTON_H
//animationbutton.cpp
#include "animationbutton.h"
Animationbutton::Animationbutton(QWidget *parent) : QWidget(parent)
{
enter=true;
leave=false;
pixWidth=0;
oldWidth=0;
pixHeight=0;
oldHeight=0;
enterAnimation=new QPropertyAnimation(this,""); //新建动画类进入动画
enterAnimation->setStartValue(0); //设置属性起始值
enterAnimation->setEndValue(5); //设置属性终止值
enterAnimation->setDuration(200); //设置动画运行时长200毫秒
connect(enterAnimation,SIGNAL(valueChanged(QVariant)),this,SLOT(enterImageChanged(QVariant))); //关联信号槽函数
leaveAnimation=new QPropertyAnimation(this,""); //新建动画类离开动画
leaveAnimation->setStartValue(0);
leaveAnimation->setEndValue(5);
leaveAnimation->setDuration(200);
connect(leaveAnimation,SIGNAL(valueChanged(QVariant)),this,SLOT(leaveImageChanged(QVariant)));
connect(this,SIGNAL(clicked()),this,SLOT(mouseClicked())); //关联鼠标单击事件信号槽
}
Animationbutton::~Animationbutton()
{
delete enterAnimation;
delete leaveAnimation;
}
void Animationbutton::enterEvent(QEvent *)
{
enter=true;
leave=false;
pixWidth=oldWidth-25;
pixHeight=oldHeight-25;
enterAnimation->start();
}
void Animationbutton::leaveEvent(QEvent *)
{
enter=false;
leave=true;
pixWidth=oldWidth;
pixHeight=oldHeight;
leaveAnimation->start();
}
void Animationbutton::paintEvent(QPaintEvent *)
{
if (image.isEmpty())
{
return;
}
QPainter painter(this); //在此窗口创建qpainter类
painter.setRenderHint(QPainter::Antialiasing,true); //开启反锯齿
QPixmap pix(image); //创建画布
pix=pix.scaled(targetWidth,targetHeight,Qt::IgnoreAspectRatio,Qt::SmoothTransformation); //以目标宽高以填充模式
if ((enter||leave)&&(!enter||!leave))
{
int pixX=rect().center().x()-targetWidth/2; //获取画布位置左上角横坐标
int pixY=rect().center().y()-targetHeight/2; //获取画布位置左上角纵坐标
QPoint point(pixX,pixY); //创建画布左上角坐标
painter.drawPixmap(point,pix); //在窗口绘制
painter.drawText(QRectF(0,height()-20,width(),20),Qt::AlignCenter,text); //以居中模式将文本显示在矩形类QRECTF所定义的区域中
//QRectF(a,b,c,d),定义一块左上角坐标(a,b)的,宽c,高d的矩形区域
}
}
void Animationbutton::mousePressEvent(QMouseEvent *e)
{
mousePos=QPoint(e->x(),e->y());
}
void Animationbutton::mouseReleaseEvent(QMouseEvent *e)
{
if(mousePos==QPoint(e->x(),e->y()))
emit clicked();
}
void Animationbutton::enterImageChanged(QVariant index) //index定义的动画属性值
{
int i=index.toInt();
targetWidth=pixWidth+i*5;
targetHeight=pixHeight+i*5;
update(); //更新动画
}
void Animationbutton::leaveImageChanged(QVariant index)
{
int i=index.toInt();
targetWidth=pixWidth-i*5;
targetHeight=pixHeight-i*5;
update();
}
void Animationbutton::setImage(QString image)
{
this->image=image;
QPixmap pix(image);
pixWidth=pix.width();
pixHeight=pix.height();
oldWidth=pixWidth;
oldHeight=pixHeight;
targetWidth=pixWidth-25; //设置图片初始大小
targetHeight=pixHeight-25;
update();
}
void Animationbutton::setText(QString text)
{
this->text=text;
update();
}
void Animationbutton::setStackedWidgets(QStackedWidget *stackedWidget,int i)
{
sWidget=stackedWidget;
curi=i;
}
void Animationbutton::setCurrentWidget()
{
if(sWidget)
{
sWidget->setCurrentIndex(curi);
}
}
void Animationbutton::mouseClicked()
{
setCurrentWidget();
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)