QT之自绘圆形进度条

1、此封装类来源于网友feiyangqingyun(QQ:517216493),自己为了调用进行了稍稍改动,原作者的下载地址:https://download.csdn.net/download/zhangxiaoyu_sy/10176752。喜欢的可以自行下载。

2、封装类如下:

#ifndef ROUNDPLOT_H
#define ROUNDPLOT_H

/**
 * 作者:feiyangqingyun(QQ:517216493) 2016-10-14
 * 本控件来源于网络(原作者:不详),本人重写90%的代码
 * 1:增加设置已使用/未使用百分比颜色
 * 2:增加设置目标值背景色
 * 3:增加设置外边框背景色
 * 4:增加设置中央圆环背景色
 * 5:增加设置旋转角度
 * 6:修正为任意大小自动缩放
 */

#include <QWidget>

class RoundPlot : public QWidget
{
	Q_OBJECT
public:
	RoundPlot(QWidget *parent = 0);
	~RoundPlot();

protected:
	void paintEvent(QPaintEvent *);
	void drawDial(QPainter *painter);
	void drawBgOut(QPainter *painter);
	void drawBgRound(QPainter *painter);
	void drawBgCenter(QPainter *painter);
	void drawText(QPainter *painter);

private:
	double minValue;//最小值
	double maxValue;//最大值
	double value;//目标值
	double angle;//起始旋转角度
    int precision;//精确度,小数点几位
	QString unit;//单位

	double valuePercent;//目标值百分比

	QColor usedColor;//已使用百分比颜色
	QColor freeColor;//未使用百分比颜色

	QColor rangeTextColor;//范围值文字颜色
	QColor valueTextColor;//目标值文字颜色

	QColor valueBgColor;//目标值背景色
	QColor outBgColor;//外边框背景色
	QColor centerBgColorStart;//中间圆环渐变背景起始颜色
	QColor centerBgColorEnd;//中间圆环渐变背景结束颜色

public:
	//获取最小值
	double getMinValue()const
	{
		return minValue;
	}

	//获取最大值
	double getMaxValue()const
	{
		return maxValue;
	}

	//获取目标值
	double getValue()const
	{
		return value;
	}

	//获取旋转角度
	double getAngle()const
	{
		return angle;
	}

	//获取小数点后几位
    int getPrecision()const
	{
        return precision;
	}

	//获取单位
	QString getUnit()const
	{
		return unit;
	}

public slots:
	//设置最大最小值-范围值
	void setRange(double minValue, double maxValue);
	void setRange(int minValue, int maxValue);

	//设置目标值
	void setValue(double value);
	void setValue(int value);

	//设置旋转角度
	void setAngle(double angle);

	//设置小数点后几位
    void setPrecision(int precision);

	//设置文字后面的单位
	void setUnit(QString unit);

	//设置已使用百分比颜色
	void setUsedColor(QColor usedColor);
	//设置未使用百分比颜色
	void setFreeColor(QColor freeColor);

	//设置范围值文字颜色
	void setRangeTextColor(QColor rangeTextColor);
	//设置目标值文字颜色
	void setValueTextColor(QColor valueTextColor);

	//设置目标值背景色
	void setValueBgColor(QColor valueBgColor);
	//设置外边框背景色
	void setOutBgColor(QColor outBgColor);
	//设置中央圆环背景色
	void setCenterBgColor(QColor centerBgColorStart, QColor centerBgColorEnd);
};

#endif // ROUNDPLOT_H
#include "roundplot.h"
#include <QPainter>
#include <QTimer>
#include <QDebug>

RoundPlot::RoundPlot(QWidget *parent) : QWidget(parent)
{
	/*
	    利用调色板在paintEvent()之前填充背景色
	*/
	setAutoFillBackground(true);
	QPalette palette = this->palette();
	palette.setColor(QPalette::Window, QColor(255, 255, 255));
	setPalette(palette);

	minValue = 0;
	maxValue = 100;
	value = 0;
	precision = 0;
	angle = 40;
	unit = "";

	valuePercent = 0;

	usedColor = QColor(165, 220, 62);
	freeColor = QColor(215, 215, 215);

	rangeTextColor = QColor(137, 137, 137);
	valueTextColor = QColor(52, 155, 218);

	valueBgColor = QColor(239, 239, 239);
	outBgColor = QColor(233, 233, 233);

	centerBgColorStart = QColor(45, 204, 112);
	centerBgColorEnd = QColor(51, 152, 219);
}

RoundPlot::~RoundPlot()
{
}

void RoundPlot::paintEvent(QPaintEvent *)
{
	int width = this->width();
	int height = this->height();

	//绘制准备工作,启用反锯齿,平移坐标轴中心,等比例缩放
	QPainter painter(this);
	painter.setRenderHint(QPainter::Antialiasing);
	painter.translate(width / 2, height / 2);

	int side = qMin(width, height);
	painter.scale(side / 200.0, side / 200.0);

	//绘制已使用百分比及未使用百分比进度
	drawDial(&painter);
	//绘制最外框圆形背景
	drawBgOut(&painter);
	//绘制中间圆环渐变背景
	drawBgRound(&painter);
	//绘制最里框百分比文字圆形背景
	drawBgCenter(&painter);
	//绘制范围值及当前值文字
	drawText(&painter);
}

void RoundPlot::drawDial(QPainter *painter)
{
	int radius = 95;
	double lineWidth = 2.5;
	painter->save();
	painter->rotate(angle);

	//根据起始旋转的角度计算每次坐标需要旋转的角度,按照100等分计算
	//每次旋转的角度=360-(起始角度*2--分左右)/100
	double rotate = (double)(360 - (angle * 2)) / 100;

	//绘制已使用百分比
	painter->setPen(QPen(usedColor, lineWidth));

	/*
	    通过每次旋转坐标系,来绘制一条直线,最终组成一个圆
	*/
	for (double i = 0; i < valuePercent; i++) {
		painter->drawLine(0, radius, 0, radius / 1.2);
		painter->rotate(rotate);
	}

	//绘制未使用百分比
	painter->setPen(QPen(freeColor, lineWidth));

	for (double i = valuePercent; i < 100; i++) {
		painter->drawLine(0, radius, 0, radius / 1.2);
		painter->rotate(rotate);
	}

	painter->restore();
}

/*
    绘制外层圆
*/
void RoundPlot::drawBgOut(QPainter *painter)
{
	int radius = 70;
	painter->save();
	painter->setPen(Qt::NoPen);
	painter->setBrush(outBgColor);
	painter->drawEllipse(-radius, -radius, radius * 2, radius * 2);
	painter->restore();
}

/*
    绘制中间渐变圆
*/
void RoundPlot::drawBgRound(QPainter *painter)
{
	int radius = 50;
	painter->save();
	QConicalGradient conicalGradient(radius, radius, 360);
	conicalGradient.setColorAt(0, centerBgColorStart);
	conicalGradient.setColorAt(1.0, centerBgColorEnd);
	painter->setPen(Qt::NoPen);
	painter->setBrush(conicalGradient);
	painter->drawEllipse(-radius, -radius, radius * 2, radius * 2);
	painter->restore();
}

/*
    绘制中心圆
*/
void RoundPlot::drawBgCenter(QPainter *painter)
{
	int radius = 30;
	painter->save();
	painter->setPen(Qt::NoPen);
	painter->setBrush(valueBgColor);
	painter->drawEllipse(-radius, -radius, radius * 2, radius * 2);
	painter->restore();
}

void RoundPlot::drawText(QPainter *painter)
{
	int radius = 100;
	painter->save();

	QString strValue = QString("%1%2").arg(QString::number(value, 'f', precision)).arg('%');
	QString strMinValue = QString("%1%2").arg(minValue).arg(unit);
	QString strMaxValue = QString("%1%2").arg(maxValue).arg(unit);

	painter->setFont(QFont("Arial", 13));
	painter->setPen(QPen(valueTextColor));
	QFontMetricsF fm = QFontMetricsF(painter->font());
	QSizeF size = fm.size(Qt::TextSingleLine, strValue);
	painter->drawText(-size.width() / 2, size.height() / 3, strValue);

	painter->setFont(QFont("Arial", 8));
	painter->setPen(QPen(rangeTextColor));
	fm = QFontMetricsF(painter->font());
	size = fm.size(Qt::TextSingleLine, strMinValue);
	painter->drawText(-radius / 2 - size.width() / 2 + 8, 80, strMinValue);
	size = fm.size(Qt::TextSingleLine, strMaxValue);
	painter->drawText(radius / 2 - size.width() / 2 - 8, 80, strMaxValue);

	painter->restore();
}

void RoundPlot::setRange(double minValue, double maxValue)
{
	//如果最小值大于或者等于最大值则不设置
	if (minValue >= maxValue) {
		return;
	}

	this->minValue = minValue;
	this->maxValue = maxValue;
}

void RoundPlot::setRange(int minValue, int maxValue)
{
	setRange((double)minValue, (double)maxValue);
}

void RoundPlot::setValue(double value)
{
	if (value < minValue) {
		this->value = minValue;
	} else if (value > maxValue) {
		this->value = maxValue;
	} else {
		this->value = value;
	}

	valuePercent = 100 * (this->value - this->minValue) / (this->maxValue - this->minValue);
	update();
}

void RoundPlot::setValue(int value)
{
	setValue((double)value);
}

void RoundPlot::setAngle(double angle)
{
	this->angle = angle;
	update();
}

void RoundPlot::setPrecision(int precision)
{
	//精确度最多为 3
	if (precision <= 3) {
		this->precision = precision;
		update();
	}
}

void RoundPlot::setUnit(QString unit)
{
	this->unit = unit;
	update();
}

void RoundPlot::setUsedColor(QColor usedColor)
{
	this->usedColor = usedColor;
	update();
}

void RoundPlot::setFreeColor(QColor freeColor)
{
	this->freeColor = freeColor;
	update();
}

void RoundPlot::setRangeTextColor(QColor rangeTextColor)
{
	this->rangeTextColor = rangeTextColor;
	update();
}

void RoundPlot::setValueTextColor(QColor valueTextColor)
{
	this->valueTextColor = valueTextColor;
	update();
}

void RoundPlot::setValueBgColor(QColor valueBgColor)
{
	this->valueBgColor = valueBgColor;
	update();
}

void RoundPlot::setOutBgColor(QColor outBgColor)
{
	this->outBgColor = outBgColor;
	update();
}

void RoundPlot::setCenterBgColor(QColor centerBgColorStart, QColor centerBgColorEnd)
{
	this->centerBgColorStart = centerBgColorStart;
	this->centerBgColorEnd = centerBgColorEnd;
	update();
}

3、使用方法:

1)创建对象:

RoundPlot* m_rp;
m_rp = new RoundPlot(this);

2)初始化操作:

m_rp->setGeometry(20,20,300,300);
m_rp->setUsedColor(QColor(41, 137, 219));
	m_rp->setRangeTextColor(QColor(103, 103, 103));
	m_rp->setValueTextColor(QColor(250, 250, 250));
	m_rp->setValueBgColor(QColor(45, 169, 222));
	m_rp->setOutBgColor(QColor(202, 225, 255));
	m_rp->setCenterBgColor(QColor(255, 0, 0), QColor(0, 255, 0));

3)不断设置进度值,改变进度条进度:

m_rp->setValue(value);

猜你喜欢

转载自blog.csdn.net/u012372584/article/details/81385883