QT自定义控件——圆环进度条

进度条应该是界面开发中最常用来做传输文件,加载配置等等待操作并可以提供一个直观的进度。

核心代码:

头文件

class RoundProgressBarPrivate;
class LIB_CUSTOMCONTROLSSHARED_EXPORT RoundProgressBar : public QWidget
{
    Q_OBJECT
    Q_PROPERTY(double minimum READ minimum WRITE setMinimum)
    Q_PROPERTY(double maximum READ maximum WRITE setMaximum)
    Q_PROPERTY(quint16 progressWidth READ progressWidth WRITE setProgressWidth)
    Q_PROPERTY(double value READ value WRITE setValue NOTIFY valueChanged)
    Q_PROPERTY(bool textVisible READ isTextVisible WRITE setTextVisible)
    Q_PROPERTY(QColor progressColor READ progressColor WRITE setProgressColor)
    Q_PROPERTY(QColor backgroundColor READ backgroundColor WRITE setBackgroundColor)
public:
    explicit RoundProgressBar(QWidget *parent = 0);

    //设置最大最小值,默认0~100
    void setMinimum(double minimum);
    void setMaximum(double maximum);
    double  minimum();
    double  maximum();

    //设置进度条宽度
    void setProgressWidth(quint16 width);
    quint16 progressWidth();

    //设置文本显示格式,与普通的qprogressbar使用方法相同
    void setFormat(const QString &format);
    QString format() const;
    //大小值
    double value();
    //百分比值
    double percent();

    //是否显示文本
    bool isTextVisible();
    void setTextVisible(bool visible);

    //进度条颜色
    QColor progressColor() const;
    void setProgressColor(const QColor &color);

    //背景颜色
    QColor backgroundColor() const;
    void setBackgroundColor(const QColor &color);
signals:
    void valueChanged(int);
public Q_SLOTS:
    //设置当前值
    void setValue(double value);
    //设置范围
    void setRange(double minimum, double maximum);
protected:
    void paintEvent(QPaintEvent *event);
private:
    QSharedPointer<RoundProgressBarPrivate> d_ptr;
    Q_DECLARE_PRIVATE(RoundProgressBar)
    Q_DISABLE_COPY(RoundProgressBar)


};

核心实现代码

     绘制事件

void RoundProgressBar::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event);
    Q_D(RoundProgressBar);
    QStylePainter painter(this);
    //设置反锯齿
//    painter.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform | QPainter::Qt4CompatiblePainting);
    d->drawRound(&painter);
    if(d->bTextVisible)
        d->drawText(&painter);
}
void RoundProgressBarPrivate::drawRound(QStylePainter *p)
{
    Q_Q(RoundProgressBar);
    p->setRenderHint(QPainter::Antialiasing,true);
    QRect drawRect = q->rect();
    int radius = qMin(q->rect().width(),q->rect().height());
    drawRect.setSize(QSize(radius,radius));
    drawRect.moveCenter(q->rect().center());
    QRect borderRect = drawRect;
    QRect backGroundRect = drawRect;
    QRegion region(drawRect,QRegion::Ellipse);
    //计算背景区域
    backGroundRect.setSize(QSize(drawRect.width()-m_progressWidth-default_border,drawRect.height()-m_progressWidth-default_border));
    backGroundRect.moveCenter(drawRect.center());
    //计算border区域
    borderRect.setSize(QSize(drawRect.width()-m_progressWidth,drawRect.height()-m_progressWidth));
    borderRect.moveCenter(drawRect.center());
    QRegion region_backGround(backGroundRect,QRegion::Ellipse);
    QRegion region_border(borderRect,QRegion::Ellipse);
    //外部圆环路径
    QPainterPath backGroundPath;
    backGroundPath.addRegion(region.subtracted(region_border));
    //border路径
    QPainterPath borderPath;
    borderPath.addRegion(region_border.subtracted(region_backGround));
    //绘制外部圆环
    p->fillPath(backGroundPath,QColor(255,255,255));
    //绘制border
//    p->fillPath(borderPath,m_progressColor);//不需要绘制
    //绘制内部圆
    p->setPen(m_backgroundColor);
    p->drawEllipse(borderRect);
    //计算进度
    int angle = q->percent()*360;
    //绘制进度条
    p->setBrush(QBrush(m_progressColor));
    p->setPen(Qt::NoPen);
    if(angle > 0)
        p->drawPath(arcPath(drawRect,90,-angle,m_progressWidth/2));

}
//计算进度路径
QPainterPath RoundProgressBarPrivate::arcPath(QRectF rect, int startAngle, int angleLength, int arcHeight)
{
    QPainterPath path;
    path.moveTo(rect.center());
    path.arcTo(rect, startAngle, angleLength);

    QPainterPath subPath;
    subPath.addEllipse(rect.adjusted(arcHeight, arcHeight, -arcHeight, -arcHeight));

    // path为扇形 subPath为椭圆
    path -= subPath;
    return path;
}

最终效果

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值