代码:
#ifndef COLORGRADIENTROUNDEDBUTTON_H
#define COLORGRADIENTROUNDEDBUTTON_H
#include <QAbstractButton>
#include <QTimer>
struct doubleColor
{
doubleColor(QColor frist = Qt::red,QColor second = Qt::blue)
:fristColor(frist),secondColor(second)
{}
QColor fristColor;
QColor secondColor;
bool operator !=(const doubleColor & c)
{
return (this->fristColor != c.fristColor) || (this->secondColor != c.secondColor);
}
};
Q_DECLARE_METATYPE(doubleColor)
class ColorGradientRoundedButton : public QAbstractButton
{
Q_OBJECT
public:
ColorGradientRoundedButton(QWidget *parent = nullptr);
~ColorGradientRoundedButton()override;
protected:
void paintEvent(QPaintEvent *event)override;
void enterEvent(QEnterEvent *event)override;
void leaveEvent(QEvent *event)override;
private:
void onTimer();
doubleColor startColor;
doubleColor endColor;
enum class ChangeModel
{
Plus,
Minus
};
QTimer timer;
int rectX{0};
ChangeModel rectXChangeModel;
};
#endif // COLORGRADIENTROUNDEDBUTTON_H
#include "colorgradientroundedbutton.h"
#include <QPainter>
#include <QPaintEvent>
#include <QGraphicsDropShadowEffect>
#include <QDebug>
#include <QPainterPath>
#include <QRandomGenerator>
QColor getRandomColor()
{
return QColor(QRandomGenerator::global()->bounded(255),
QRandomGenerator::global()->bounded(255),
QRandomGenerator::global()->bounded(255));
}
ColorGradientRoundedButton::ColorGradientRoundedButton(QWidget *parent)
: QAbstractButton(parent)
{
startColor = doubleColor(getRandomColor(),getRandomColor());
endColor = doubleColor(getRandomColor(),getRandomColor());
this->setMinimumSize(180,50);
setMouseTracking(true);
QGraphicsDropShadowEffect * effect = new QGraphicsDropShadowEffect(this);
setGraphicsEffect(effect);
effect->setOffset(0,0);
effect->setBlurRadius(25);
effect->setColor(Qt::black);
timer.setInterval(40);
connect(&timer,&QTimer::timeout,this,&ColorGradientRoundedButton::onTimer);
}
ColorGradientRoundedButton::~ColorGradientRoundedButton()
{
}
void ColorGradientRoundedButton::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing,true);
auto rect = event->rect();
auto rectWidth = rect.width();
QPainterPath path;
path.addRoundedRect(rect,25,25);
painter.setClipPath(path);
painter.drawRect(rect);
QLinearGradient linearGradient1(QPoint(-rectX,0),QPoint(rectWidth - rectX,0));
linearGradient1.setColorAt(0,startColor.fristColor);
linearGradient1.setColorAt(1,startColor.secondColor);
painter.fillRect(QRect(-rectX,0,rectWidth,rect.height()),linearGradient1);
QLinearGradient linearGradient2(QPoint(rectWidth - rectX,0),QPoint(rectWidth * 2 - rectX,0));
linearGradient2.setColorAt(0,endColor.fristColor);
linearGradient2.setColorAt(1,endColor.secondColor);
painter.fillRect(QRect(rectWidth - rectX,0,rectWidth,rect.height()),linearGradient2);
auto font = painter.font();
font.setBold(true);
font.setPixelSize(20);
painter.setFont(font);
painter.setPen(Qt::white);
painter.drawText(rect,Qt::AlignCenter,text());
}
void ColorGradientRoundedButton::onTimer()
{
if(rectXChangeModel == ChangeModel::Plus)
{
rectX += (rect().width() / 6);
if(rectX >= rect().width())
{
rectX = rect().width();
timer.stop();
}
}
else
{
rectX -= (rect().width() / 6);
if(rectX <= 0)
{
rectX = 0;
timer.stop();
}
}
update();
}
void ColorGradientRoundedButton::enterEvent(QEnterEvent *event)
{
if(timer.isActive())
timer.stop();
rectXChangeModel = ChangeModel::Plus;
timer.start();
QWidget::enterEvent(event);
}
void ColorGradientRoundedButton::leaveEvent(QEvent *event)
{
if(timer.isActive())
timer.stop();
rectXChangeModel = ChangeModel::Minus;
timer.start();
QWidget::leaveEvent(event);
}
使用示例:
QWidget w;
w.setPalette(Qt::white);
auto vb = new QVBoxLayout;
vb->setSpacing(15);
for(int i = 0;i < 8;++i)
{
auto btn = new ColorGradientRoundedButton;
btn->setText(QString("按钮%1").arg(i));
vb->addWidget(btn);
}
w.setLayout(vb);
w.show();
效果: