Qt自定義sink風格按鈕

爲了滿足工作中控件多樣性的要求,一些控件的風格需要通過重寫畫家事件的方式進行自定義;
實現sink風格按鈕的效果圖如下:
在這裏插入圖片描述
純代碼實現思路:
產生按鈕下沉的效果是利用了視覺誤差原理,通過更改背景顏色以及圖標的位置,呈現出按鈕動態改變的效果。

按鈕未按下狀態繪製代碼:

void SinkButton::drawUnSinkRect(QPainter *painter)
{
    painter->save();
    QBrush brush;
    brush.setColor(mReleaBgColor);
    brush.setStyle(Qt::SolidPattern);
    painter->setBrush(brush);
    painter->drawRect(0,0,width(),height());
    QPen pen;
    pen.setColor(mInterColor);
    pen.setWidth(mWidth*2);
    painter->setPen(pen);
    painter->drawLine(width(),0,width(),height());
    painter->drawLine(0,height(),width(),height());
    pen.setColor(Qt::white);
    painter->setPen(pen);
    pen.setWidth(0);
    painter->drawLine(0,0,width(),0);
    painter->drawLine(0,0,0,height());
    pen.setColor(Qt::black);
    pen.setWidth(0);
    painter->setPen(pen);
    painter->drawLine(width(),0,width(),height());
    painter->drawLine(0,height(),width(),height());
    painter->restore();

}

按鈕按下狀態代碼:

void SinkButton::drawSinkedRect(QPainter *painter)
{
    painter->save();
    QBrush brush;
    brush.setColor(mPressBgColor);
    brush.setStyle(Qt::SolidPattern);
    painter->setBrush(brush);
    painter->drawRect(0,0,width(),height());
    QPen pen;
    pen.setColor(Qt::white);
    painter->setPen(pen);
    painter->drawLine(width(),0,width(),height());
    painter->drawLine(0,height(),width(),height());

    pen.setColor(mInterColor);
    pen.setWidth(mWidth*2);
    painter->setPen(pen);
    painter->drawLine(0,0,width(),0);
    painter->drawLine(0,0,0,height());
    pen.setColor(Qt::black);
    pen.setWidth(0);
    painter->setPen(pen);
    painter->drawLine(0,0,width(),0);
    painter->drawLine(0,0,0,height());
    painter->restore();
}

完整的源碼:
sinkbutton.h

#ifndef SINKBUTTON_H
#define SINKBUTTON_H
#include <QPushButton>
#include <QColor>

class SinkButton:public QPushButton
{

public:
    SinkButton(QWidget *parent = nullptr);
    ~SinkButton();
    void setText(const QString &text);
    //其它顏色的設置也可以自己定義接口
    void setPressBgColor(const QColor& pressBgColor);
    void setReleaBgColor(const QColor& releaseBgColor);
    void setIcon(const QString &iconName);

protected:
    void paintEvent(QPaintEvent *event);
    void mousePressEvent(QMouseEvent *event);
    void mouseReleaseEvent(QMouseEvent *event);
    void drawText(QPainter *painter);//添加文本
    void drawIcon(QPainter *painter);//添加圖標

public slots:
    void drawUnSinkRect(QPainter *painter);//正常狀態
    void drawSinkedRect(QPainter *painter);//下沉狀態
    void drawDisBleRect(QPainter *painter);//禁用狀態

private:
    bool pressed;
    int mWidth;
    int mDisWidth;
    QString mText;
    QColor mPressBgColor;
    QColor mReleaBgColor;
    QColor mFrameColor;
    QColor mInterColor;
    QColor mDisColor;
    QColor mDisSlidColor;
    QString mIconName;

};

#endif // SINKBUTTON_H

sinkbutton.cpp

#include "sinkbutton.h"
#include <QPainter>
#include <QtDebug>
SinkButton::SinkButton(QWidget *parent):QPushButton(parent)
{
    pressed = false;
    mWidth = 2;
    mDisWidth = 5;
    mPressBgColor = QColor("#D8912C");
    mReleaBgColor = QColor("#9DBFE6");
    mFrameColor = Qt::black;
    mInterColor = QColor("#45382B");
    mDisColor = QColor("#CBE2F9");
    mDisSlidColor = QColor("#514F4F");
    mText = "";
    mIconName = "";
}
SinkButton:: ~SinkButton()
{

}

void SinkButton::mousePressEvent(QMouseEvent *event)
{
    pressed = true;
    update();
}
void SinkButton::mouseReleaseEvent(QMouseEvent *event)
{
    pressed = false;
    update();
}


void SinkButton::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);
    painter.setRenderHint(QPainter::TextAntialiasing);

    if(isEnabled()){
        if(!pressed){
            drawUnSinkRect(&painter);
        }else{
            drawSinkedRect(&painter);
        }
    }else{
        drawDisBleRect(&painter);
    }

    drawIcon(&painter);
    drawText(&painter);
}

void SinkButton::drawUnSinkRect(QPainter *painter)
{
    painter->save();
    QBrush brush;
    brush.setColor(mReleaBgColor);
    brush.setStyle(Qt::SolidPattern);
    painter->setBrush(brush);
    painter->drawRect(0,0,width(),height());
    QPen pen;
    pen.setColor(mInterColor);
    pen.setWidth(mWidth*2);
    painter->setPen(pen);
    painter->drawLine(width(),0,width(),height());
    painter->drawLine(0,height(),width(),height());
    pen.setColor(Qt::white);
    painter->setPen(pen);
    pen.setWidth(0);
    painter->drawLine(0,0,width(),0);
    painter->drawLine(0,0,0,height());
    pen.setColor(Qt::black);
    pen.setWidth(0);
    painter->setPen(pen);
    painter->drawLine(width(),0,width(),height());
    painter->drawLine(0,height(),width(),height());
    painter->restore();
}

void SinkButton::drawSinkedRect(QPainter *painter)
{
    painter->save();
    QBrush brush;
    brush.setColor(mPressBgColor);
    brush.setStyle(Qt::SolidPattern);
    painter->setBrush(brush);
    painter->drawRect(0,0,width(),height());
    QPen pen;
    pen.setColor(Qt::white);
    painter->setPen(pen);
    painter->drawLine(width(),0,width(),height());
    painter->drawLine(0,height(),width(),height());
    pen.setColor(mInterColor);
    pen.setWidth(mWidth*2);
    painter->setPen(pen);
    painter->drawLine(0,0,width(),0);
    painter->drawLine(0,0,0,height());
    pen.setColor(Qt::black);
    pen.setWidth(0);
    painter->setPen(pen);
    painter->drawLine(0,0,width(),0);
    painter->drawLine(0,0,0,height());
    painter->restore();
}

void SinkButton::drawDisBleRect(QPainter *painter)
{
    painter->save();
    QBrush brush;
    brush.setColor(mDisColor);
    brush.setStyle(Qt::SolidPattern);
    painter->setBrush(brush);
    painter->drawRect(0,0,width(),height());
    QPen pen;
    pen.setColor(mDisSlidColor);
    pen.setWidth(mDisWidth);
    painter->setPen(pen);
    painter->drawRect(0,0,width(),height());
    painter->restore();
}


void SinkButton::drawInerRect(QPainter *painter)
{
    QPen pen;
    pen.setStyle(Qt::DotLine);
    pen.setColor(mFrameColor);
    painter->setPen(pen);
    painter->drawRect(mWidth,mWidth,width()-2*mWidth,height()-2*mWidth);
}


void SinkButton::drawText(QPainter *painter)
{
    painter->save();
    if(pressed){
        painter->drawText(mWidth,mWidth,width()-mWidth,height()-mWidth,Qt::AlignCenter,mText);
    }else{
       painter->drawText(0,0,width(),height(),Qt::AlignCenter,mText);
    }
    painter->restore();
}

void SinkButton::drawIcon(QPainter *painter)
{
    painter->save();
    QPixmap pixmap(mIconName);
    if(pressed){
        painter->drawPixmap((width()-pixmap.width())/2+mWidth,(height()-pixmap.height())/2+mWidth,pixmap.width(),pixmap.height(),pixmap);
    }else{
        painter->drawPixmap((width()-pixmap.width())/2,(height()-pixmap.height())/2,pixmap.width(),pixmap.height(),pixmap);
    }

    painter->restore();
}



void SinkButton::setIcon(const QString &iconName)
{
    mIconName = iconName;
    update();
}



void SinkButton::setText(const QString &text)
{
    mText = text;
    update();
}


void SinkButton::setPressBgColor(const QColor& pressBgColor)
{
    mPressBgColor = pressBgColor;
    update();
}

void SinkButton::setReleaBgColor(const QColor& releaBgColor)
{
    mReleaBgColor = releaBgColor;
    update();
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章