前言
- 本文源码基于开源的代码改进而来, 具体出处无法溯源。
效果

功能
- 支持鼠标左键点击进图条设置值
- 支持显示当前数值
- 支持设置填充部分和未填充部分的颜色
- 开箱即用
源码
ProgressBar.h
#pragma once
#include <QWidget>
class ProgressBar : public QWidget
{
	Q_OBJECT
public:
    explicit ProgressBar(QWidget *parent = nullptr);
    virtual ~ProgressBar();
	void setMaxValue(int nValue);
    int maxValue()const;
	void setMinValue(int nValue);
    int minValue()const;
	void setRange(int nMin, int nMax);
    int value()const;
	/// 滑块没有填充的部分颜色,比如:"#FF00FF"
	void setBKRectBrush(const QString& brush);
    QString backRectBrush()const;
	/// 设置填充矩形的渐变色
	void setFillRectColor(const QLinearGradient& lg);
	/// 
	/// @brief:	设置圆角矩形的值, 默认20 
	/// @param:	dbRadius 
	/// @return:	void 
	///				
	void setRadius(double dbRadius);
	/// 
	/// @brief:	设置当前值显示的颜色,
	/// @param:	str  比如: #FF00FF 
	/// @return:	void 
	///				
	void setValueTextColor(const QString& str);
	/// 
	/// @brief:	设置当前文字的大小 
	/// @param:	size 
	/// @return:	void 
	///				
	void setValueTextPointSize(int size);
protected:
	virtual void paintEvent(QPaintEvent *event)override;
	virtual void mouseMoveEvent(QMouseEvent *event)override;
	virtual void mousePressEvent(QMouseEvent *event)override;
	virtual void mouseReleaseEvent(QMouseEvent *event)override;
    virtual bool eventFilter(QObject *o, QEvent *e)override;
private:
	void drawBackRect(QPainter& painter);
	void drawProcess(QPainter& painter);
	void drawCurrentValueText(QPainter& painter);
private:
	void updateValue(int nCurValue);
	void initValue();
	void initUISetting();
signals:
    void sigValueChanged(qint32 nValue);
public slots:
    void setValue(int nValue);
private:
	struct stRange
	{
		int m_nMin{0};
		int m_nMax{100};
	}m_range;
	int m_nCurValue{0};
	double m_dbCurPercent{0.0};
	double m_dbRadius{16};
	QString m_bkRectBrush{};
	bool m_bPressed{false};
	/// 文字的颜色, 比如: "#FF00FF"
	QString m_valueTextColor{"#FCFCFC"};
	/// 文字的大小
	int		m_valueTextPointSize{ 12 };
	/// 填充进度的渐变色
	QLinearGradient		m_fillRectLineGradient{};
};
ProgressBar.cpp
#include "ProgressBar.h"
#include <QPainter>
#include <QMouseEvent>
#include <QFontMetrics>
#include <QLinearGradient>
ProgressBar::ProgressBar(QWidget* parent)
	: QWidget(parent)
{
	initUISetting();
	initValue();
	setWindowFlags(Qt::FramelessWindowHint);
	setAttribute(Qt::WA_TranslucentBackground);
}
ProgressBar::~ProgressBar()
{
}
void ProgressBar::setMaxValue(int nValue)
{
	if (nValue < m_range.m_nMin)
	{
		nValue = m_range.m_nMin;
	}
	m_range.m_nMax = nValue;
	updateValue(0);
}
int ProgressBar::maxValue() const
{
	return m_range.m_nMax;
}
void ProgressBar::setMinValue(int nValue)
{
	if (nValue > m_range.m_nMax)
	{
		nValue = m_range.m_nMax;
	}
	m_range.m_nMin = nValue;
	updateValue(0);
}
int ProgressBar::minValue() const
{
	return m_range.m_nMin;
}
void ProgressBar::setRange(int nMin, int nMax)
{
	if (nMax < nMin)
	{
		nMax = nMin;
	}
	m_range.m_nMin = nMin;
	m_range.m_nMax = nMax;
	updateValue(0);
}
void ProgressBar::setValue(int nValue)
{
	updateValue(nValue);
}
int ProgressBar::value() const
{
	return m_nCurValue;
}
void ProgressBar::setBKRectBrush(const QString& brush)
{
	if (m_bkRectBrush == brush)
	{
		return;
	}
	m_bkRectBrush = brush;
	update();
}
QString ProgressBar::backRectBrush() const
{
	return m_bkRectBrush;
}
/// 
/// @brief:	setFillRectColor 
/// @param:	lg 
/// @return:	void 
///				
void ProgressBar::setFillRectColor(const QLinearGradient& lg)
{
	if (m_fillRectLineGradient == lg)
	{
		return;
	}
	m_fillRectLineGradient = lg;
	update();
}
void ProgressBar::setRadius(double dbRadius)
{
	if (qFuzzyCompare(m_dbRadius, dbRadius))
	{
		return;
	}
	m_dbRadius = dbRadius;
	update();
}
/// 
/// @brief:	设置当前值显示的颜色 
/// @param:	str 
/// @return:	void 
///				
void ProgressBar::setValueTextColor(const QString& str)
{
	m_valueTextColor = str;
	update();
}
/// 
/// @brief:	setValueTextPointSize 
/// @param:	size 
/// @return:	void 
///				
void ProgressBar::setValueTextPointSize(int size)
{
	m_valueTextPointSize = size;
}
void ProgressBar::paintEvent(QPaintEvent* event)
{
	QPainter painter(this);
	painter.setPen(Qt::NoPen);
	painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
	painter.setBrush(Qt::NoBrush);
	drawBackRect(painter);
	drawProcess(painter);
	drawCurrentValueText(painter);
}
void ProgressBar::mouseMoveEvent(QMouseEvent* event)
{
	if (m_bPressed)
	{
		m_dbCurPercent = (event->pos().x() - m_dbRadius) * 1.0 / (width() - 2 * m_dbRadius);
		m_dbCurPercent = std::min(1.0, m_dbCurPercent);
		m_dbCurPercent = std::max(0.0, m_dbCurPercent);
		m_nCurValue = (m_range.m_nMax - m_range.m_nMin) * m_dbCurPercent;
		emit sigValueChanged(m_nCurValue);
		update();
	}
	QWidget::mouseMoveEvent(event);
}
void ProgressBar::mousePressEvent(QMouseEvent* event)
{
	m_bPressed = true;
	m_dbCurPercent = (event->pos().x() - m_dbRadius) * 1.0 / (width() - 2 * m_dbRadius);
	m_nCurValue = (m_range.m_nMax - m_range.m_nMin) * m_dbCurPercent;
	emit sigValueChanged(m_nCurValue);
	update();
}
void ProgressBar::mouseReleaseEvent(QMouseEvent* event)
{
	m_bPressed = false;
	QWidget::mouseReleaseEvent(event);
}
bool ProgressBar::eventFilter(QObject* o, QEvent* e)
{
	return QWidget::eventFilter(o, e);
}
void ProgressBar::drawBackRect(QPainter& painter)
{
	painter.save();
	painter.setBrush(QColor(m_bkRectBrush));
	painter.drawRoundedRect(QRect(0, 0, width() , this->height()), m_dbRadius, m_dbRadius);
	painter.restore();
}
void ProgressBar::drawProcess(QPainter& painter)
{
	painter.save();
	
	QRect rectf(0, 0, width() * m_dbCurPercent, this->height());
	QLinearGradient lineGradient = m_fillRectLineGradient;
	lineGradient.setStart(QPoint(0, 0));
	lineGradient.setFinalStop(QPoint(width(), 0));
	painter.setBrush(lineGradient);
	painter.drawRoundedRect(rectf, m_dbRadius, m_dbRadius);
	painter.restore();
}
/// 
/// @brief:	drawCurrentValueText 
/// @param:	painter 
/// @return:	void 
///				
void ProgressBar::drawCurrentValueText(QPainter& painter)
{
	painter.save();
	const QString valueText = QString::number(static_cast<int>(m_dbCurPercent * 100));
	painter.setPen(QPen(QColor(m_valueTextColor), 2));
	painter.setBrush(Qt::NoBrush);
	{
		QFont tmpFont = painter.font();
		tmpFont.setPointSize(m_valueTextPointSize);
		tmpFont.setBold(true);
		painter.setFont(tmpFont);
	}
	QFontMetrics fm(painter.font());
	int fontW = fm.width(valueText);
	QSize textSize{ fontW, height()};
	QRect valueRect{QPoint(width() - textSize.width() - 10, 0), textSize};
	painter.drawText(valueRect, Qt::AlignVCenter | Qt::AlignRight, valueText);
	painter.restore();
}
void ProgressBar::updateValue(int nCurValue)
{
	if (m_nCurValue == nCurValue)
	{
		return;
	}
	m_nCurValue = nCurValue;
	if (m_range.m_nMax == m_range.m_nMin)
		m_dbCurPercent = 0;
	else
		m_dbCurPercent = m_nCurValue * 1.0 / (m_range.m_nMax - m_range.m_nMin);
	update();
}
void ProgressBar::initValue()
{
	m_range = { 0, 100 };
	m_nCurValue = 0;
	m_dbCurPercent = 0;
	m_bkRectBrush = {"#5D6B99"};
	m_bPressed = false;
	m_fillRectLineGradient.setColorAt(0, QColor("#00b09b"));
	m_fillRectLineGradient.setColorAt(1, QColor("#96c93d"));
}
void ProgressBar::initUISetting()
{
	//setCursor(QCursor(Qt::PointingHandCursor));
	setMouseTracking(true);
	setFocusPolicy(Qt::StrongFocus);
}