百分比儀表盤,主要的應用場景是展現銷售完成率、產品合格率等,也能夠做爲一個進度百分比展現,能夠獨立設置對應的標題文字,標題文字的顏色和總體的顏色均可以單獨設置,建議設置成統一的風格,這樣會顯得更加美觀,貼一張星空圖做爲背景就更美觀,本控件也是做爲大屏UI界面的一個子控件,用來展現產品的合格率。c++
#ifndef GAUGEPERCENT_H #define GAUGEPERCENT_H /** * 百分比儀表盤控件 做者:feiyangqingyun(QQ:517216493) 2018-8-30 * 1:可設置範圍值,支持負數值 * 2:可設置精確度,最大支持小數點後3位 * 3:可設置大刻度數量/小刻度數量 * 4:可設置開始旋轉角度/結束旋轉角度 * 5:可設置儀表盤的標題 * 6:可設置外圓背景/內圓背景/餅圓三種顏色/刻度尺顏色/文字顏色 * 7:自適應窗體拉伸,刻度尺和文字自動縮放 * 8:可自由拓展各類漸變色,各圓的半徑 */ #include <QWidget> #ifdef quc #if (QT_VERSION < QT_VERSION_CHECK(5,7,0)) #include <QtDesigner/QDesignerExportWidget> #else #include <QtUiPlugin/QDesignerExportWidget> #endif class QDESIGNER_WIDGET_EXPORT GaugePercent : public QWidget #else class GaugePercent : public QWidget #endif { Q_OBJECT Q_PROPERTY(double minValue READ getMinValue WRITE setMinValue) Q_PROPERTY(double maxValue READ getMaxValue WRITE setMaxValue) Q_PROPERTY(double value READ getValue WRITE setValue) Q_PROPERTY(int precision READ getPrecision WRITE setPrecision) Q_PROPERTY(int scaleMajor READ getScaleMajor WRITE setScaleMajor) Q_PROPERTY(int scaleMinor READ getScaleMinor WRITE setScaleMinor) Q_PROPERTY(int startAngle READ getStartAngle WRITE setStartAngle) Q_PROPERTY(int endAngle READ getEndAngle WRITE setEndAngle) Q_PROPERTY(QColor arcColor READ getArcColor WRITE setArcColor) Q_PROPERTY(QColor scaleColor READ getScaleColor WRITE setScaleColor) Q_PROPERTY(QColor scaleNumColor READ getScaleNumColor WRITE setScaleNumColor) Q_PROPERTY(QColor textColor READ getTextColor WRITE setTextColor) Q_PROPERTY(QColor titleColor READ getTitleColor WRITE setTitleColor) Q_PROPERTY(QColor baseColor READ getBaseColor WRITE setBaseColor) Q_PROPERTY(QColor bgColor READ getBgColor WRITE setBgColor) Q_PROPERTY(QString title READ getTitle WRITE setTitle) public: explicit GaugePercent(QWidget *parent = 0); ~GaugePercent(); protected: void paintEvent(QPaintEvent *); void drawArc(QPainter *painter); void drawCircle(QPainter *painter); void drawScale(QPainter *painter); void drawScaleNum(QPainter *painter); void drawValue(QPainter *painter); void drawTitle(QPainter *painter); private: double minValue; //最小值 double maxValue; //最大值 double value; //目標值 int precision; //精確度,小數點後幾位 int scaleMajor; //大刻度數量 int scaleMinor; //小刻度數量 int startAngle; //開始旋轉角度 int endAngle; //結束旋轉角度 QColor arcColor; //圓弧顏色 QColor scaleColor; //刻度尺顏色 QColor scaleNumColor; //刻度值顏色 QColor textColor; //文字顏色 QColor titleColor; //標題顏色 QColor baseColor; //基準顏色 QColor bgColor; //背景顏色 QString title; //標題 public: double getMinValue() const; double getMaxValue() const; double getValue() const; int getPrecision() const; int getScaleMajor() const; int getScaleMinor() const; int getStartAngle() const; int getEndAngle() const; QColor getArcColor() const; QColor getScaleColor() const; QColor getScaleNumColor() const; QColor getTextColor() const; QColor getTitleColor() const; QColor getBaseColor() const; QColor getBgColor() const; QString getTitle() const; QSize sizeHint() const; QSize minimumSizeHint() const; public Q_SLOTS: //設置範圍值 void setRange(double minValue, double maxValue); void setRange(int minValue, int maxValue); //設置最大最小值 void setMinValue(double minValue); void setMaxValue(double maxValue); //設置目標值 void setValue(double value); void setValue(int value); //設置精確度 void setPrecision(int precision); //設置主刻度數量 void setScaleMajor(int scaleMajor); //設置小刻度數量 void setScaleMinor(int scaleMinor); //設置開始旋轉角度 void setStartAngle(int startAngle); //設置結束旋轉角度 void setEndAngle(int endAngle); //設置圓弧顏色 void setArcColor(const QColor &arcColor); //設置刻度尺顏色 void setScaleColor(const QColor &scaleColor); //設置刻度值顏色 void setScaleNumColor(const QColor &scaleNumColor); //設置文本顏色 void setTextColor(const QColor &textColor); //設置標題顏色 void setTitleColor(const QColor &titleColor); //設置基準顏色 void setBaseColor(const QColor &baseColor); //設置背景顏色 void setBgColor(const QColor &bgColor); //設置標題 void setTitle(const QString &title); Q_SIGNALS: void valueChanged(int value); }; #endif // GAUGEPERCENT_H
void GaugePercent::paintEvent(QPaintEvent *) { int width = this->width(); int height = this->height(); int side = qMin(width, height); //繪製準備工做,啓用反鋸齒,平移座標軸中心,等比例縮放 QPainter painter(this); painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing); //繪製背景 if (bgColor != Qt::transparent) { painter.setPen(Qt::NoPen); painter.fillRect(this->rect(), bgColor); } painter.translate(width / 2, height / 2); painter.scale(side / 200.0, side / 200.0); //繪製圓弧 drawArc(&painter); //繪製圓弧進度小球 drawCircle(&painter); //繪製刻度線 drawScale(&painter); //繪製刻度值 drawScaleNum(&painter); //繪製當前值 drawValue(&painter); //繪製標題 drawTitle(&painter); } void GaugePercent::drawArc(QPainter *painter) { int radius = 95; painter->save(); painter->setBrush(Qt::NoBrush); QPen pen; pen.setWidthF(5); pen.setCapStyle(Qt::RoundCap); //計算總範圍角度,當前值範圍角度,剩餘值範圍角度 double angleAll = 360.0 - startAngle - endAngle; double angleCurrent = angleAll * ((value - minValue) / (maxValue - minValue)); double angleOther = angleAll - angleCurrent; QRectF rect = QRectF(-radius, -radius, radius * 2, radius * 2); //繪製當前進度圓弧 pen.setColor(arcColor); painter->setPen(pen); painter->drawArc(rect, (270 - startAngle - angleCurrent) * 16, angleCurrent * 16); //繪製剩餘進度圓弧 pen.setColor(scaleColor); painter->setPen(pen); painter->drawArc(rect, (270 - startAngle - angleCurrent - angleOther) * 16, angleOther * 16); painter->restore(); } void GaugePercent::drawCircle(QPainter *painter) { int radius = 6; int offset = 83; painter->save(); painter->setPen(Qt::NoPen); painter->setBrush(arcColor); painter->rotate(startAngle); double degRotate = (360.0 - startAngle - endAngle) / (maxValue - minValue) * (value - minValue); painter->rotate(degRotate); painter->drawEllipse(-radius, radius + offset, radius * 2, radius * 2); painter->restore(); } void GaugePercent::drawScale(QPainter *painter) { int radius = 90; painter->save(); painter->rotate(startAngle); int steps = (scaleMajor * scaleMinor); double angleStep = (360.0 - startAngle - endAngle) / steps; QPen pen; pen.setColor(scaleColor); pen.setCapStyle(Qt::RoundCap); pen.setWidthF(1.0); painter->setPen(pen); for (int i = 0; i <= steps; i++) { painter->drawLine(0, radius - 5, 0, radius); painter->rotate(angleStep); } painter->restore(); } void GaugePercent::drawScaleNum(QPainter *painter) { int radius = 75; painter->save(); painter->setPen(scaleNumColor); double startRad = (360 - startAngle - 90) * (M_PI / 180); double deltaRad = (360 - startAngle - endAngle) * (M_PI / 180) / scaleMajor; for (int i = 0; i <= scaleMajor; i++) { double sina = qSin(startRad - i * deltaRad); double cosa = qCos(startRad - i * deltaRad); double value = 1.0 * i * ((maxValue - minValue) / scaleMajor) + minValue; QString strValue = QString("%1").arg((double)value, 0, 'f', precision); double textWidth = fontMetrics().width(strValue); double textHeight = fontMetrics().height(); int x = radius * cosa - textWidth / 2; int y = -radius * sina + textHeight / 4; painter->drawText(x, y, strValue); } painter->restore(); } void GaugePercent::drawValue(QPainter *painter) { int radius = 100; painter->save(); painter->setPen(textColor); QFont font; font.setPixelSize(30); painter->setFont(font); QRectF textRect(-radius, 0, radius * 2, radius / 3); QString strValue = QString("%1%").arg((double)value, 0, 'f', precision); painter->drawText(textRect, Qt::AlignCenter, strValue); painter->restore(); } void GaugePercent::drawTitle(QPainter *painter) { int radius = 100; painter->save(); painter->setPen(titleColor); QFont font; font.setPixelSize(20); painter->setFont(font); QRectF textRect(-radius, radius / 3, radius * 2, radius / 3); painter->drawText(textRect, Qt::AlignCenter, title); painter->restore(); }