Qt编写自定义控件:彩色渐变圆角按钮之二

代码:

#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();

效果:

 

Guess you like

Origin blog.csdn.net/kenfan1647/article/details/121412899
Recommended