liudianwu |
2016-10-14 13:42 |
Qt编写动态圆形进度条
最近在整理用户自定义控件,包含开源的和修正的及自己写的。 参照Qt自己的命名,统一定义了一些书写规范:
1:所有命名均为首字母小写,例如setValue; 2:私有变量及函数不建议使用下划线; 3:设置用set开头,获取值用get开头; 4:公共方法和公有槽都要注释,私有的变量和方法建议注释。 5:方法及变量类似的含义的,可以靠在一起分组,不同分组间空一行。 6:所有公共方法,函数体超过一行的在头文件中只声明,实现文件中写具体方法。 7:void类型的公共方法全部改为公共槽。
头文件依次排列顺序: public:构造函数及析构函数 protected:重写的方法,例如paintEvent等。 private:私有变量 private slots:私有槽函数 public:公共方法 public slots:公有槽函数 signal:信号
- #ifndef ROUNDPLOT_H
#define ROUNDPLOT_H
#include <QWidget>
/** * 作者:feiyangqingyun(QQ:517216493) 2016-10-14 * 本控件来源于网络(原作者:不详),本人重写90%的代码 */
class RoundPlot : public QWidget { Q_OBJECT public: RoundPlot(QWidget *parent = 0); ~RoundPlot();
protected: void paintEvent(QPaintEvent *event);
private: int minValue; //最小值 int maxValue; //最大值 int value; //目标值 QString unit; //单位
int currentValue; //当前值 int step; //步长,动态变化时每次增加的步长
QColor usedColor; //已使用百分比颜色 QColor freeColor; //未使用百分比颜色
QColor rangeTextColor; //范围值文字颜色 QColor valueTextColor; //目标值文字颜色
QColor valueBgColor; //目标值背景色 QColor outBgColor; //外边框背景色 QColor centerBgColorStart; //中间圆环渐变背景起始颜色 QColor centerBgColorEnd; //中间圆环渐变背景结束颜色
QFont rangeTextFont; //范围值文字字体 QFont valueTextFont; //目标值文字字体
QTimer *updateTimer; //绘制定时器
private slots: void updateValue();
public: //获取最小值 int getMinValue()const { return minValue; }
//获取最大值 int getMaxValue()const { return maxValue; }
//获取目标值 int getValue()const { return value; }
//获取单位 QString getUnit()const { return unit; }
public slots: //设置最大最小值-范围值 void setRange(int minValue, int maxValue); //设置目标值 void setValue(int value); //设置文字后面的单位 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);
//设置范围值文字字体 void setRangeTextFont(QFont rangeTextFont); //设置目标值文字字体 void setValueTextFont(QFont valueTextFont); };
#endif // ROUNDPLOT_H
- #include "roundplot.h"
#include "qtimer.h" #include "qpainter.h" #include "qapplication.h" #include "qevent.h" #include "qdesktopwidget.h" #include "qdebug.h"
RoundPlot::RoundPlot(QWidget *parent) : QWidget(parent, Qt::FramelessWindowHint) { setMinimumSize(167, 167); setAutoFillBackground(true); QPalette palette = this->palette(); palette.setColor(QPalette::Background, QColor(255, 255, 255)); setPalette(palette);
minValue = 0; maxValue = 100; value = 0; unit = "";
currentValue = 0; step = maxValue / 100;
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);
rangeTextFont = QFont("Arial", 10, QFont::Normal); valueTextFont = QFont("Arial", 15, QFont::Bold);
updateTimer = new QTimer(this); updateTimer->setInterval(10); connect(updateTimer, SIGNAL(timeout()), this, SLOT(updateValue())); }
RoundPlot::~RoundPlot() { if (updateTimer->isActive()) { updateTimer->stop(); } }
void RoundPlot::paintEvent(QPaintEvent *event) { Q_UNUSED(event) int width = this->width(); int height = this->height();
//直径取宽高中最短的一个 int diameter = width > height ? height : width;
//绘制准备工作,旋转坐标轴中心 QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing); painter.setRenderHint(QPainter::SmoothPixmapTransform); painter.translate(width / 2, height / 2); painter.save(); painter.rotate(40);
//自动计算比例关系 double percent = (double)100 / (maxValue - minValue); int currentPercent = currentValue * percent; int maxPercent = maxValue * percent;
//自动计算位置比例 double diameterLine = ((double)3 / 167) * diameter; double diameterWidth = ((double)70 / 167) * diameter; double diameterHeight = ((double)80 / 167) * diameter; double diameter1 = ((double)55 / 167) * diameter; double diameter2 = ((double)35 / 167) * diameter; double diameter3 = ((double)30 / 167) * diameter; double diameter4 = ((double)80 / 167) * diameter; double diameter5 = ((double)135 / 167) * diameter;
//绘制当前百分比 painter.setPen(QPen(usedColor, diameterLine));
for (int i = minValue; i < currentPercent; i++) { painter.drawLine(0, diameterWidth, 0, diameterHeight); painter.rotate(2.8); }
//绘制空余百分比 painter.setPen(QPen(freeColor, diameterLine));
for (int i = currentPercent; i < maxPercent; i++) { painter.drawLine(0, diameterWidth, 0, diameterHeight); painter.rotate(2.8); }
painter.restore();
//绘制最外框圆形背景 painter.translate(-width / 2, -height / 2); painter.setBrush(outBgColor); painter.setPen(QPen(outBgColor, 15)); painter.drawEllipse(QRectF((width / 2 - diameter1), (height / 2 - diameter1), diameter1 * 2, diameter1 * 2));
//绘制中间框圆形渐变背景 QConicalGradient conicalGradient(width / 2, height / 2, 90); conicalGradient.setColorAt(0, centerBgColorStart); conicalGradient.setColorAt(1.0, centerBgColorEnd); painter.setPen(QPen(QBrush(conicalGradient), 30)); painter.drawEllipse(QRectF((width / 2 - diameter2), (height / 2 - diameter2), diameter2 * 2, diameter2 * 2));
//绘制最里框百分比文字圆形背景 painter.setPen(Qt::NoPen); painter.setBrush(valueBgColor); painter.drawEllipse(QRectF((width / 2 - diameter3), (height / 2 - diameter3), diameter3 * 2, diameter3 * 2));
//绘制百分比文字及范围值文字 painter.setPen(QPen(valueTextColor)); painter.setFont(valueTextFont); painter.drawText(0, 0, width, height, Qt::AlignCenter, tr("%1%2").arg(currentValue).arg(unit)); painter.setPen(QPen(rangeTextColor)); painter.setFont(rangeTextFont); painter.drawText(0, 0, width - diameter4, height + diameter5, Qt::AlignCenter, tr("%1%2").arg(minValue).arg(unit)); painter.drawText(0, 0, width + diameter4, height + diameter5, Qt::AlignCenter, tr("%1%2").arg(maxValue).arg(unit)); }
void RoundPlot::updateValue() { if (currentValue >= value) { updateTimer->stop(); return; }
currentValue = currentValue + step; update(); }
void RoundPlot::setRange(int minValue, int maxValue) { if (updateTimer->isActive()) { updateTimer->stop(); }
currentValue = minValue; this->minValue = minValue; this->maxValue = maxValue;
//如果目标值不在范围值内,则重新设置目标值 if (value < minValue || value > maxValue) { setValue(value); }
//自动计算步长,步长=最大值/100 step = maxValue / 100; }
void RoundPlot::setValue(int value) { //如果目标值比最小值小则取最小值,如果目标值比最大值大则取最大值 if (value < minValue) { this->value = minValue; } else if (value > maxValue) { this->value = maxValue; } else { this->value = value; }
updateTimer->start(); }
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(); }
void RoundPlot::setRangeTextFont(QFont rangeTextFont) { this->rangeTextFont = rangeTextFont; update(); }
void RoundPlot::setValueTextFont(QFont valueTextFont) { this->valueTextFont = valueTextFont; update(); }
使用方法:
- #include "frmroundplot.h"
#include "ui_frmroundplot.h" #include "myhelper.h" #include "control/roundplot.h"
frmRoundPlot::frmRoundPlot(QWidget *parent) : QWidget(parent), ui(new Ui::frmRoundPlot) { ui->setupUi(this); ui->widget2->setUsedColor(QColor(41, 137, 219)); ui->widget2->setFreeColor(QColor(50, 50, 50)); ui->widget2->setRangeTextColor(QColor(103, 103, 103)); ui->widget2->setValueTextColor(QColor(250, 250, 250)); ui->widget2->setValueBgColor(QColor(45, 169, 222)); ui->widget2->setOutBgColor(QColor(202, 225, 255)); ui->widget2->setCenterBgColor(QColor(67, 205, 128), QColor(60, 179, 113)); ui->widget2->setRangeTextFont(QFont("Microsoft Yahei", 10, QFont::Normal)); ui->widget2->setValueTextFont(QFont("Microsoft Yahei", 18, QFont::Normal)); on_pushButton_clicked(); }
frmRoundPlot::~frmRoundPlot() { delete ui; }
void frmRoundPlot::on_pushButton_clicked() { int min = ui->txtMin->text().toInt(); int max = ui->txtMax->text().toInt(); int current = ui->txtCurrent->text().toInt(); QString unit = ui->txtUnit->text();
ui->widget1->setRange(min, max); ui->widget2->setRange(min, max); ui->widget1->setValue(current); ui->widget2->setValue(current); ui->widget1->setUnit(unit); ui->widget2->setUnit(unit); }
效果 [attachment=15885]
|
|