Qt/C++开源控件 圆形进度条
- 简约风格: 设计简洁,没有多余的元素,清晰地显示了当前进度。
- 颜色对比: 使用了亮色的蓝色来标示进度,与深色背景形成鲜明对比,使得进度指示一目了然。
- 清晰的刻度: 刻度线清晰,尽管没有标注所有数字,但通过较长的刻度线在50和100的位置,用户可以很容易地估计进度。
- 指针设计: 指针末端带有一个圆形装饰,这不仅美观而且提高了指针指向的清晰度。
- 中心百分比显示: 进度的数值以大号字体在控件中心显示,用户可以快速读取数值信息。

#ifndef CIRCULARPROGRESS_H
#define CIRCULARPROGRESS_H
#include <QWidget>
#include <QColor>
class CircularProgress : public QWidget
{
Q_OBJECT
Q_PROPERTY(int value READ value WRITE setValue NOTIFY valueChanged)
Q_PROPERTY(QColor backgroundColor READ backgroundColor WRITE setBackgroundColor)
Q_PROPERTY(QColor scaleColor READ scaleColor WRITE setScaleColor)
public:
explicit CircularProgress(QWidget *parent = 0);
~CircularProgress();
int value() const;
QColor backgroundColor() const;
QColor scaleColor() const;
public slots:
void setValue(int newValue);
void setBackgroundColor(const QColor &color);
void setScaleColor(const QColor &color);
signals:
void valueChanged(int newValue);
protected:
void paintEvent(QPaintEvent *event) override;
private:
int m_value;
QColor m_backgroundColor;
QColor m_progressColor;
QColor m_textColor;
QColor m_scaleColor;
void drawBackground(QPainter &painter);
void drawProgress(QPainter &painter);
void drawHandle(QPainter &painter, double angle);
void drawScale(QPainter &painter);
};
#endif
#include "circularprogress.h"
#include <QPainter>
#include <QPainterPath>
#include <QtMath>
CircularProgress::CircularProgress(QWidget *parent):
QWidget(parent),
m_value(0),
m_backgroundColor(QColor(100, 100, 100)),
m_progressColor(Qt::green),
m_textColor(Qt::white),
m_scaleColor(Qt::white)
{
}
CircularProgress::~CircularProgress()
{
}
int CircularProgress::value() const
{
return m_value;
}
QColor CircularProgress::backgroundColor() const
{
return m_backgroundColor;
}
QColor CircularProgress::scaleColor() const
{
return m_scaleColor;
}
void CircularProgress::setValue(int newValue)
{
if (newValue < 0 || newValue > 100)
{
return;
}
if (m_value != newValue)
{
m_value = newValue;
emit valueChanged(newValue);
update();
}
}
void CircularProgress::setBackgroundColor(const QColor &color)
{
if (m_backgroundColor != color)
{
m_backgroundColor = color;
update();
}
}
void CircularProgress::setScaleColor(const QColor &color)
{
if (m_scaleColor != color)
{
m_scaleColor = color;
update();
}
}
void CircularProgress::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
drawBackground(painter);
drawScale(painter);
drawProgress(painter);
drawHandle(painter, (m_value / 100.0) * 270.0);
}
void CircularProgress::drawBackground(QPainter &painter)
{
painter.fillRect(rect(), m_backgroundColor);
}
void CircularProgress::drawProgress(QPainter &painter)
{
int width = this->width() - 10;
int height = this->height() - 10;
int radius = qMin(width, height) / 2 - 30;
QRectF rectangle(width / 2 - radius, height / 2 - radius, 2 * radius, 2 * radius);
painter.setPen(QPen(m_progressColor, 5));
int startAngle = -135 * 16;
int spanAngle = -(m_value / 100.0) * 270 * 16;
painter.drawArc(rectangle, startAngle, spanAngle);
}
void CircularProgress::drawHandle(QPainter &painter, double angle)
{
int width = this->width() - 10;
int height = this->height() - 10;
int radius = qMin(width, height) / 2 - 30;
int handleRadius = 5;
double radian = qDegreesToRadians(-225 + angle);
int centerX = width / 2 + (radius) * cos(radian);
int centerY = height / 2 + (radius) * sin(radian);
painter.setBrush(m_progressColor);
painter.drawEllipse(QPointF(centerX, centerY), handleRadius, handleRadius);
}
void CircularProgress::drawScale(QPainter &painter)
{
int width = this->width() - 10;
int height = this->height() - 10;
int radius = qMin(width, height) / 2 - 45;
painter.setPen(QPen(m_scaleColor, 2));
for (int i = 0; i <= 100; i += 10)
{
double angle = -225 + (i / 100.0) * 270;
double radian = qDegreesToRadians(angle);
int outerX = width / 2 + radius * cos(radian);
int outerY = height / 2 + radius * sin(radian);
int innerX = width / 2 + (radius - 20) * cos(radian);
int innerY = height / 2 + (radius - 20) * sin(radian);
painter.drawLine(QPointF(innerX, innerY), QPointF(outerX, outerY));
QString text = QString::number(i);
QFontMetrics fm(painter.font());
int textX = width / 2 + (radius + 25) * cos(radian) - fm.width(text) / 2;
int textY = height / 2 + (radius + 25) * sin(radian) - fm.height() / 3;
painter.drawText(textX, textY, text);
}
painter.setPen(m_textColor);
painter.setFont(QFont("Arial", 20, QFont::Bold));
painter.drawText(rect(), Qt::AlignCenter, QString::number(m_value) + "%");
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库