QStyle 绘制一个自定义QProgressBar

详细介绍

 .h

#ifndef STYLE_PROGRESS_H
#define STYLE_PROGRESS_H

#include <QProxyStyle>
#include <QPainter>
#include <QStyleOption>
#include <QLinearGradient>
#include <QDebug>

class style_progress : public QProxyStyle
{
    Q_OBJECT

public:
    style_progress();
    ~style_progress();

public:
    void drawPrimitive(PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget = 0) const;
    void drawControl(ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget = 0) const;
    QRect subElementRect(SubElement element, const QStyleOption *option, const QWidget *widget) const;

    void drawLabel(ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget = 0)const;
    void drawContains(ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget = 0)const;
};

#endif // STYLE_PROGRESS_H

 .cpp

#include "style_progress.h"

style_progress::style_progress()
{
}

style_progress::~style_progress()
{

}

void style_progress::drawPrimitive(QStyle::PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const
{
    if(element == PE_IndicatorProgressChunk)//绘制进度指示
    {
        qDebug()<<option->rect;
        QRect rect = option->rect;
        int cx =12*100/rect.width();
        int cy =12*100/rect.height();
        painter->save();
        painter->setPen(Qt::NoPen);
        QLinearGradient ln(0,0,rect.width(),rect.height());
        ln.setColorAt(0.0,QColor(255,182,193));
        ln.setColorAt(0.5, QColor(100,149,237));
        ln.setColorAt(1.0, QColor(255,222,173));
        painter->setBrush(ln);
        painter->drawRect(rect);
        painter->restore();
        return;
    }
    QProxyStyle::drawPrimitive(element,option,painter,widget);
}

void style_progress::drawControl(QStyle::ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const
{
    switch (element) {
    case CE_ProgressBar:
        if(const QStyleOptionProgressBar *pv2 = qstyleoption_cast<const QStyleOptionProgressBar*>(option))
        {
            drawControl(CE_ProgressBarContents,pv2,painter,widget);
            if(pv2->textVisible)
            {
                drawControl(CE_ProgressBarLabel,pv2,painter,widget);
            }
        }
        break;
    case CE_ProgressBarContents:
        drawContains(CE_ProgressBarContents,option,painter,widget);
        break;
    case CE_ProgressBarLabel:
        drawLabel(CE_ProgressBarLabel,option,painter,widget);
        break;
    case CE_ProgressBarGroove:
    default:
        return QProxyStyle::drawControl(element,option,painter,widget);
    }
}

QRect style_progress::subElementRect(QStyle::SubElement element, const QStyleOption *option, const QWidget *widget) const
{
    switch (element) {
    case SE_ProgressBarContents:
        return option->rect;
    case SE_ProgressBarLabel:
        if(const QStyleOptionProgressBar* v = qstyleoption_cast<const QStyleOptionProgressBar*>(option))
        {
            QStyleOptionProgressBarV2 v2(*v);
            if(v2.orientation == Qt::Vertical)
            {
                return QRect(v2.rect.x(),v2.rect.height()*0.4,v2.rect.width(),v2.rect.height()*0.2);
            }
            else
            {
                return QRect(v2.rect.width()*0.4,v2.rect.y(),v2.rect.width()*0.2,v2.rect.height());
            }
        }
    default:
        return QProxyStyle::subElementRect(element,option,widget);
    }
}

void style_progress::drawLabel(QStyle::ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget)const
{
    if(const QStyleOptionProgressBar* v = qstyleoption_cast<const QStyleOptionProgressBar*>(option))
    {
        QStyleOptionProgressBarV2 v2(*v);
        QRect textRect = subElementRect(SE_ProgressBarLabel,option,widget);
        QPalette pa = v2.palette;
        pa.setColor(QPalette::Text,QColor(Qt::red));
        QString text = "aa:"+v2.text;
        painter->drawText(textRect,Qt::AlignCenter,text);
    }
}

void style_progress::drawContains(QStyle::ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget)const
{
    if(const QStyleOptionProgressBar* v = qstyleoption_cast<const QStyleOptionProgressBar*>(option))
    {
        QStyleOptionProgressBarV2 v2(*v);
        QRect rect_contens = subElementRect(SE_ProgressBarContents,option,widget);
        painter->save();
        painter->setPen(Qt::transparent);
        painter->setBrush(QColor(88,88,88,63));

        int cx = 12*100/rect_contens.width();
        int cy = 12*100/rect_contens.height();
        painter->drawRoundRect(rect_contens,cx,cy);
        painter->restore();

        if(v2.orientation == Qt::Vertical)
        {
            v2.rect.setHeight((v2.progress*v->rect.height())/v2.maximum);
        }
        else
        {
            v2.rect.setWidth((v2.progress*v->rect.width())/v2.maximum);
        }
        drawPrimitive(PE_IndicatorProgressChunk,&v2,painter,widget);
    }
}