环形进度条

如下:

步骤(重写paintEvent):

  1. 将painter移动到中心
  2. 确定半径为宽高中较小值的一半,防止缩放变形,优先填满较小的那一边
  3. 绘制底部圆
  4. 绘制中间的扇形,且画刷采用锥形渐变
  5. 最顶部的圆
  6. 绘制文字,且画在最中心

注:每一步都可以开放接口(这里就不加了)将参数暴漏出来,让外部使用者自己设置从而定制这个外观

头文件:

注:里面的set和get方法,还有Q_PPROPERTY都是qt自己加的,点击重构就可以添加

#ifndef ANNULARPROGRESSBAR_H
#define ANNULARPROGRESSBAR_H

#include <QObject>
#include <QWidget>
#include<QPainter>

//环形进度条
class AnnularProgressBar : public QWidget
{
    Q_OBJECT
    Q_PROPERTY(int value READ value WRITE setValue NOTIFY valueChanged FINAL)
    Q_PROPERTY(int min READ min WRITE setMin NOTIFY minChanged FINAL)
    Q_PROPERTY(int max READ max WRITE setMax NOTIFY maxChanged FINAL)
public:
    explicit AnnularProgressBar(QWidget *parent = nullptr);
    int value() const;
    void setValue(int newValue);

    int min() const;
    void setMin(int newMin);

    int max() const;
    void setMax(int newMax);

protected:
    void paintEvent(QPaintEvent* ev) override;

private:
    int mValue=50;//进度条的当前值
    int mMin=0;//最小值
    int mMax=100;//最大值

signals:
    void valueChanged();
    void minChanged();
    void maxChanged();
};

#endif // ANNULARPROGRESSBAR_H

cpp文件:

#include "annularprogressbar.h"

AnnularProgressBar::AnnularProgressBar(QWidget *parent)
    : QWidget{parent}
{}

void AnnularProgressBar::paintEvent(QPaintEvent *ev)
{
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);
    painter.translate(width()/2,height()/2);//移动到中心

    //底部圆的半径、扇形的半径
    int r=std::min(width()/2,height()/2)-5;//防止缩放变形,优先填满较小的那一边
    //底部圆对应的矩形
    QRect rectBottom=QRect(-r,-r,2*r,2*r);
    //顶部部圆对应的矩形
    QRect rectTop=rectBottom.adjusted(r/5,r/5,-r/5,-r/5);//左上角和右下角往里缩r/5px

    //1、先画最底部的圆
    painter.save();
    painter.setPen(Qt::NoPen);//去掉轮廓
    painter.setBrush(Qt::gray);//设置画刷 填充为红色
    painter.drawEllipse(rectBottom);
    painter.restore();


    //2、再画中间表示进度的扇形
    painter.save();
    painter.setPen(Qt::NoPen);//去掉轮廓
    QConicalGradient cg(rectBottom.center(),90);
    cg.setColorAt(0,Qt::red);
    cg.setColorAt(1,Qt::blue);
    painter.setBrush(cg);//设置画刷 为锥形渐变
    //起始角度:90度  即0点的位置
    //跨越的角度:当前值/值范围   用这个比例*360度,就是对应的角度  前面加-号,变成顺时针画
    painter.drawPie(rectBottom,90*16,-mValue*1.0/(mMax-mMin)*360*16);
    painter.restore();

    //3、绘制顶部的圆
    painter.save();
    painter.setPen(Qt::NoPen);//去掉轮廓
    painter.setBrush(Qt::green);//设置画刷 填充为绿色
    painter.drawEllipse(rectTop);
    painter.restore();

    //4、绘制文字
    painter.save();
    painter.setPen(Qt::black);
    QFont font=painter.font();
    font.setPointSize(rectBottom.width()/4);
    font.setFamily("黑体");
    painter.setFont(font);
    //绘制在整个中心
    painter.drawText(rectBottom,Qt::AlignCenter,QString("%1%").arg(100*mValue*1.0/(mMax-mMin)));
    painter.restore();
}

int AnnularProgressBar::max() const
{
    return mMax;
}

void AnnularProgressBar::setMax(int newMax)
{
    if (mMax == newMax)
        return;
    mMax = newMax;
    emit maxChanged();
}

int AnnularProgressBar::min() const
{
    return mMin;
}

void AnnularProgressBar::setMin(int newMin)
{
    if (mMin == newMin)
        return;
    mMin = newMin;
    emit minChanged();
}

int AnnularProgressBar::value() const
{
    return mValue;
}

void AnnularProgressBar::setValue(int newValue)
{
    if(newValue>mMax)
    {
        mValue =mMax;
        return;
    }
    if(newValue<mMin)
    {
        mValue=mMin;
        return;
    }
    if (mValue == newValue)
        return;
    mValue = newValue;
    emit valueChanged();
    update();
}

知识点:

  • QRect::adjusted快速根据一个矩形进行调整得到另一个矩形
QRect QRect::adjusted(int dx1, int dy1, int dx2, int dy2) const

该成员方法可以快速根据一个矩形进行调整得到另一个矩形

其中dx1,dy1,表示原来矩形的左上角往里或者往外缩多少,都为正,则左上角往里缩,都为负,则左上角往外缩

dx2,dy2,表示原来矩形的右下角往里或者往外缩多少,都为正,则右下角往外缩,都为负,则右下角往里缩

 

  • 锥形渐变
QConicalGradient cg(rectBottom.center(),90);//渐变中心,起始角度(0为3点钟方向,逆时针)
cg.setColorAt(0,Qt::red);
cg.setColorAt(1,Qt::blue);
  • 将文本画在矩形的中心Qt::AlignCenter
//绘制文本时指定对齐方式
painter.drawText(rectBottom,Qt::AlignCenter,QString("%1%").arg(100*mValue*1.0/(mMax-mMin)));

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值