qt环形进度条控件设计

上效果

在这里插入图片描述
推荐文章:

上代码

1、 控件的h文件

#ifndef ROUNDPROGRESSBAR_H
#define ROUNDPROGRESSBAR_H

#include <QWidget>
#include <QPainter>

#define Abs(x) ((x)>=0?(x):-(x))

class RoundProgressBar : public QWidget
{
    
    
    Q_OBJECT
    Q_PROPERTY(float _value READ getValue WRITE _setValue)
public:
    enum SwitchFlags    //控制变量
    {
    
    
        defaultText =0x00000001,        //默认文字
        linearColor =0x00000004,        //内圈渐变色
        decorateDot =0x00000008,        //装饰圆点
        outterCirle =0x0000000e,        //外圈
        animation   =0x00000010,        //动画
        all         =0xffffffff        //显示所有效果
    };
    enum InnerDefaultTextStyle    //内部文字展示样式
    {
    
    
        percent     =0x00000001,        //百分比
        value       =0x00000002,        //值
        valueAndMax =0x00000004        //值与最大值
    };

    explicit RoundProgressBar(QWidget *parent = 0);
    ~RoundProgressBar();

    void setdefault(int,bool);//设置初始角度,顺时针逆时针
    void setOutterBarWidth(float);//设置外圈宽度
    void setInnerBarWidth(float);//设置内圈宽度
    void setRange(float, float);//设置范围
    void setValue(float);//设置当前值
    void setOutterColor(const QColor&);//设置外圈颜色
    void setInnerColor(const QColor&,const QColor&);//设置内圈渐变色
    void setInnerColor(const QColor&);
    void setDefaultTextColor(const QColor&);//设置默认文字颜色
    void setControlFlags(int);//设置控制命令
    void setPrecision(int); //设置显示数字精度
    //设置内圈默认文字样式
    inline void setInnerDefaultTextStyle(InnerDefaultTextStyle style){
    
    _innerDefaultTextStyle=style;}
    //获取当前值
    inline float getValue(){
    
    return _value;}

protected:
    void paintEvent(QPaintEvent *);
    void resizeEvent(QResizeEvent *event);

private:
    int _startAngle;//起始角度 范围0-360
    bool _clockWise;//顺时针
    float _outterBarWidth;//outterBar宽度
    float _innerBarWidth;//innerBar宽度
    float _dotX;//圆点矩形坐标
    float _dotY;
    float _min;//最小值,最大值,当前值
    float _max;
    float _value;
    QColor _outterColor;//外圈颜色
    QColor _startColor;//内圈渐变颜色
    QColor _endColor;
    QColor _textColor;//默认文字颜色
    int _precision; //小数点精度
    float _squareStart; //绘制正方形信息
    float _squareWidth;
    quint32 _controlFlags=0x00000000;//控制信号
    InnerDefaultTextStyle _innerDefaultTextStyle; //内圈默认文字样式

    void paintOutterBar(QPainter &);//绘制外圈
    void paintInnerBar(QPainter &);//绘制内圈
    void paintDot(QPainter &);//绘制装饰圆点
    void paintText(QPainter &);//绘制默认内置文字
    void _setValue(float); //设置当前值
    void caculateSquare(); //计算绘制正方形区域信息

};

#endif // ROUNDPROGRESSBAR_H

2、控件cpp文件

#include "roundprogressbar.h"
#include "qmath.h"
#include <QPropertyAnimation>
#include <QDebug>

RoundProgressBar::RoundProgressBar(QWidget *parent) :
    QWidget(parent),
    _value(0),
    _min(0),
    _max(100),
    _precision(0)
{
    
    
    setdefault(90,true);//设置初始角度,顺时针逆时针
    setOutterBarWidth(18);//设置默认外圈宽度
    setInnerBarWidth(16);//设置默认内圈宽度
    setRange(0,100);//设置默认范围
    setValue(75);//设置默认值
    setOutterColor(QColor(233,248,248));//设置外圈颜色
    setInnerColor(QColor(49, 177, 190),QColor(133, 243, 244)); //设置默认渐变色
    setDefaultTextColor(QColor(49,177,190));//设置默认文字颜色
    setPrecision(0);//设置默认精度
    setInnerDefaultTextStyle(RoundProgressBar::percent);//设置内圈默认文字样式
}

RoundProgressBar::~RoundProgressBar()
{
    
    

}

void RoundProgressBar::setdefault(int startAngle,bool clockWise)//设置初始角度,顺时针逆时针
{
    
    
    _startAngle=startAngle;
    _clockWise=clockWise;
}
void RoundProgressBar::setOutterBarWidth(float width)//设置外圈宽度
{
    
    
    _outterBarWidth=width;
}
void RoundProgressBar::setInnerBarWidth(float width)//设置内圈宽度
{
    
    
    _innerBarWidth=width;
}

void RoundProgressBar::setRange(float min,float max)//设置值的范围
{
    
    
    if(max<min)    //todo 和value比较
    {
    
    
        max=100; min=0;
    }
    else
    {
    
    
        _max=max; _min=min;
    }
}

void RoundProgressBar::setValue(float value)//设置当前值
{
    
    
    QPropertyAnimation* animation=new QPropertyAnimation(this,"_value");
    animation->setDuration(500);
    animation->setStartValue(_value);
    animation->setEndValue(value);
    animation->setEasingCurve(QEasingCurve::OutQuad);
    animation->start();
}

void RoundProgressBar::_setValue(float value)
{
    
    
    _value=value;
    repaint();
}
void RoundProgressBar::setOutterColor(const QColor& outterColor)//设置外圈颜色
{
    
    
    _outterColor=outterColor;
}
void RoundProgressBar::setInnerColor(const QColor& startColor,const QColor& endColor)//设置内圈渐变色
{
    
    
    _startColor=startColor;
    _endColor=endColor;
}
void RoundProgressBar::setInnerColor(const QColor& startColor)//设置内圈渐变色
{
    
    
    _startColor=startColor;
}
void RoundProgressBar::setDefaultTextColor(const QColor& textColor)
{
    
    
    _textColor=textColor;
}
void RoundProgressBar::setControlFlags(int flags)//设置控制
{
    
    
    this->_controlFlags|=flags;
}
void RoundProgressBar::setPrecision(int precision)//设置显示数字精度
{
    
    
    _precision=precision;
}

//**********************************************************************************
void RoundProgressBar::resizeEvent(QResizeEvent *event)
{
    
    
    if(_outterBarWidth>_innerBarWidth)    //根据内外圈宽度设置控件最小大小
        this->setMinimumSize(_outterBarWidth*8,_outterBarWidth*8);
    else
        this->setMinimumSize(_innerBarWidth*8,_innerBarWidth*8);
    caculateSquare();    //计算绘制正方形区域信息
}

void RoundProgressBar::paintEvent(QPaintEvent *)
{
    
    
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);
    paintOutterBar(painter);    //绘制外圈
    paintInnerBar(painter);    //绘制内圈
    paintDot(painter);    //绘制外圈
    paintText(painter);    //绘制文字
}

void RoundProgressBar::caculateSquare()//计算绘制正方形区域信息
{
    
    
    int minWidth=qMin(this->width(),this->height());
    float barWidth=qMax(_outterBarWidth,_innerBarWidth);
    _squareWidth=minWidth-barWidth-2;
    _squareStart=barWidth/2+1;
    _dotX=_squareStart+_squareWidth/2;
    _dotY=_squareStart;
}

void RoundProgressBar::paintOutterBar(QPainter &painter)//绘制外圈
{
    
    
    if(!(_controlFlags&outterCirle))
        return;
    QPen pen;
    pen.setWidth(_outterBarWidth);
    pen.setColor(_outterColor);
    painter.setPen(pen);
    QRectF rectangle(_squareStart,_squareStart,_squareWidth,_squareWidth);

    painter.drawEllipse(rectangle);    //从90度开始,逆时针旋转
}

void RoundProgressBar::paintInnerBar(QPainter& painter)//绘制内圈
{
    
    
    QPen pen;
    if(!(_controlFlags&linearColor))
        pen.setColor(_startColor);
    else
    {
    
    
        QLinearGradient gradient(0, 0, 0, _squareWidth);
        gradient.setColorAt(0, _startColor);
        gradient.setColorAt(1, _endColor);
        QBrush brush(gradient);
        pen.setBrush(brush);
    }
    pen.setWidth(_innerBarWidth);
    pen.setStyle(Qt::SolidLine);
    pen.setCapStyle(Qt::RoundCap);
    pen.setJoinStyle(Qt::RoundJoin);
    painter.setPen(pen);
    QRectF rectangle(_squareStart,_squareStart,_squareWidth,_squareWidth);
    //从90度开始,逆时针旋转
    int startAngle=_startAngle*16;
    int spanAngle=(_value-_min)/(_max-_min)*360*16*(_clockWise?-1:1);
    painter.drawArc(rectangle,startAngle,spanAngle);
}

void RoundProgressBar::paintDot(QPainter& painter)//绘制装饰圆点
{
    
    
    if(!(_controlFlags&decorateDot))
        return;
    if(_innerBarWidth<3)    //当bar宽度小于3时,便不再绘制装饰圆点
        return;
    painter.setPen(QColor(255,255,255));
    painter.setBrush(QColor(255,255,255));
    //区域为圆点绘制正方形区域
    painter.drawEllipse(_dotX-_innerBarWidth/6,_dotY-_innerBarWidth/6,_innerBarWidth/3,_innerBarWidth/3);
}

void RoundProgressBar::paintText(QPainter& painter)//绘制默认内置文字
{
    
    
    if(!(_controlFlags&defaultText))
        return;
    painter.setPen(_textColor);
    painter.setFont(QFont("Microsoft YaHei",22,75));
    switch (_innerDefaultTextStyle) {
    
    
    case value:
        painter.drawText(_squareStart,_squareStart,_squareWidth,_squareWidth,Qt::AlignCenter,QString::number(_value,'f',_precision));
        break;
    case valueAndMax:
        painter.drawText(_squareStart,_squareStart,_squareWidth,_squareWidth,Qt::AlignCenter,
                         QString::number(_value,'f',_precision)+"/"+QString::number(_max,'f',_precision));
        break;
    case percent:
        painter.drawText(_squareStart,_squareStart,_squareWidth,_squareWidth,Qt::AlignCenter,
                         QString::number(_value/_max*100,'f',_precision)+"%");
        break;
    default:
        break;
    }
}

使用示例

使用方法很简单,代码如下:

    RoundProgressBar* bar = new RoundProgressBar(this);
    bar->setOutterBarWidth(22);
    bar->setInnerBarWidth(20);
    bar->setControlFlags(RoundProgressBar::all);

或者采用提升的方式也行。

猜你喜欢

转载自blog.csdn.net/weixin_42887343/article/details/120222293