多態進度條,顧名思義,有多重狀態,其實本控件主要是用來表示百分比進度的,因爲以前已經存在了百分比進度條控件,名字被霸佔了,按照先來先得原則,只好另外取個別名叫作多態進度條,應用場景是,某種任務有三種狀態,好比正常狀態、警惕狀態、報警狀態,這三種狀態都分別有一個佔比,須要用不一樣的顏色表示,這樣就衍生出了此控件,相似於堆積圖。接下來節假日四天,能夠全身心投入研發還未完工的大屏UI程序,基礎控件部分+二級界面部分都已經作好,如今專心整合到主界面和打通數據流(採用數據庫採集+網絡採集兩種方式)。多態進度條也是爲了此項目特地定製的。c++
#ifndef PROGRESSTHREE_H #define PROGRESSTHREE_H /** * 多態進度條控件 做者:feiyangqingyun(QQ:517216493) 2019-4-30 * 1:可設置三種狀態不一樣的值 * 2:可設置三種狀態不一樣的顏色 * 3:可設置圓角角度 * 4:可設置啓用自動圓角 * 5:可設置邊框寬度+顏色 * 6:可設置是否顯示值或者百分比 * 7:可設置字體自適應大小 * 8:可設置背景顏色+文字顏色 * 9:精準計算圓角角度,解決了QSS中border-radius當進度小於圓角角度出現方形的BUG */ #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 ProgressThree : public QWidget #else class ProgressThree : public QWidget #endif { Q_OBJECT Q_PROPERTY(int value1 READ getValue1 WRITE setValue1) Q_PROPERTY(int value2 READ getValue2 WRITE setValue2) Q_PROPERTY(int value3 READ getValue3 WRITE setValue3) Q_PROPERTY(QColor color1 READ getColor1 WRITE setColor1) Q_PROPERTY(QColor color2 READ getColor2 WRITE setColor2) Q_PROPERTY(QColor color3 READ getColor3 WRITE setColor3) Q_PROPERTY(int radius READ getRadius WRITE setRadius) Q_PROPERTY(bool autoRadius READ getAutoRadius WRITE setAutoRadius) Q_PROPERTY(bool showValue READ getShowValue WRITE setShowValue) Q_PROPERTY(bool showPercent READ getShowPercent WRITE setShowPercent) Q_PROPERTY(bool autoFont READ getAutoFont WRITE setAutoFont) Q_PROPERTY(double borderWidth READ getBorderWidth WRITE setBorderWidth) Q_PROPERTY(QColor borderColor READ getBorderColor WRITE setBorderColor) Q_PROPERTY(QColor bgColor READ getBgColor WRITE setBgColor) Q_PROPERTY(QColor textColor READ getTextColor WRITE setTextColor) public: explicit ProgressThree(QWidget *parent = 0); protected: void paintEvent(QPaintEvent *); void drawBg(QPainter *painter); void drawValue(QPainter *painter); void drawValue1(QPainter *painter); void drawValue2(QPainter *painter); void drawValue3(QPainter *painter); void drawBorder(QPainter *painter); private: int value1; //值1 int value2; //值2 int value3; //值3 QColor color1; //顏色1 QColor color2; //顏色2 QColor color3; //顏色3 int radius; //圓角角度 bool autoRadius; //自動圓角 bool showValue; //顯示對應的值 bool showPercent; //顯示對應的百分比 bool autoFont; //自動字體大小 double borderWidth; //邊框寬度 QColor borderColor; //邊框顏色 QColor bgColor; //背景顏色 QColor textColor; //文字顏色 int width1; //值1寬度 int width2; //值2寬度 int width3; //值3寬度 public: int getValue1() const; int getValue2() const; int getValue3() const; QColor getColor1() const; QColor getColor2() const; QColor getColor3() const; int getRadius() const; bool getAutoRadius() const; bool getShowValue() const; bool getShowPercent() const; bool getAutoFont() const; double getBorderWidth() const; QColor getBorderColor() const; QColor getBgColor() const; QColor getTextColor() const; QSize sizeHint() const; QSize minimumSizeHint() const; public Q_SLOTS: //設置三個值 void setValue1(int value1); void setValue2(int value2); void setValue3(int value3); //設置三個顏色 void setColor1(const QColor &color1); void setColor2(const QColor &color2); void setColor3(const QColor &color3); //設置圓角+自動圓角 void setRadius(int radius); void setAutoRadius(bool autoRadius); //設置顯示值+顯示百分比+自動字體大小 void setShowValue(bool showValue); void setShowPercent(bool showPercent); void setAutoFont(bool autoFont); //設置邊框寬度+顏色 void setBorderWidth(double borderWidth); void setBorderColor(const QColor &borderColor); //設置背景顏色+文字顏色 void setBgColor(const QColor &bgColor); void setTextColor(const QColor &textColor); }; #endif // PROGRESSTHREE_H
void ProgressThree::paintEvent(QPaintEvent *) { //繪製準備工做,啓用反鋸齒,平移座標軸中心,等比例縮放 QPainter painter(this); painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing); if (autoRadius) { radius = this->height() / 2; } //繪製背景 drawBg(&painter); //繪製值1 drawValue1(&painter); //繪製值2 drawValue2(&painter); //繪製值3 drawValue3(&painter); //最後繪製邊框蓋上去 drawBorder(&painter); } void ProgressThree::drawBg(QPainter *painter) { painter->save(); painter->setPen(Qt::NoPen); painter->setBrush(bgColor); painter->drawRoundedRect(this->rect(), radius, radius); painter->restore(); } void ProgressThree::drawValue1(QPainter *painter) { painter->save(); //計算百分比以及對應的寬度 int sum = value1 + value2 + value3; double percent = (double)value1 / sum; width1 = this->width() * percent; painter->setPen(Qt::NoPen); painter->setBrush(color1); //計算繪製的區域,須要裁剪圓角部分 QPainterPath clipPath; clipPath.addRoundedRect(this->rect(), radius, radius); painter->setClipPath(clipPath); QRect rect(0, 0, width1, this->height()); painter->drawRect(rect); //繪製文字 if (showValue) { //設置文字字體+顏色 if (autoFont) { QFont font; font.setPixelSize(this->height() * 0.9); painter->setFont(font); } QString text = QString::number(value1); if (showPercent) { text = QString("%1%").arg(QString::number(percent * 100, 'f', 0)); } painter->setPen(textColor); painter->drawText(rect, Qt::AlignCenter, text); } painter->restore(); } void ProgressThree::drawValue2(QPainter *painter) { painter->save(); //計算百分比以及對應的寬度 int sum = value1 + value2 + value3; double percent = (double)value2 / sum; width2 = this->width() * percent; painter->setPen(Qt::NoPen); painter->setBrush(color2); //計算繪製的區域,須要裁剪圓角部分 QPainterPath clipPath; clipPath.addRoundedRect(this->rect(), radius, radius); painter->setClipPath(clipPath); QRect rect(width1, 0, width2, this->height()); painter->drawRect(rect); //繪製文字 if (showValue) { //設置文字字體+顏色 if (autoFont) { QFont font; font.setPixelSize(this->height() * 0.9); painter->setFont(font); } QString text = QString::number(value2); if (showPercent) { text = QString("%1%").arg(QString::number(percent * 100, 'f', 0)); } painter->setPen(textColor); painter->drawText(rect, Qt::AlignCenter, text); } painter->restore(); } void ProgressThree::drawValue3(QPainter *painter) { painter->save(); //寬度減去其餘兩個就是 int sum = value1 + value2 + value3; double percent = (double)value3 / sum; width3 = this->width() - width1 - width2; painter->setPen(Qt::NoPen); painter->setBrush(color3); //計算繪製的區域,須要裁剪圓角部分 QPainterPath clipPath; clipPath.addRoundedRect(this->rect(), radius, radius); painter->setClipPath(clipPath); QRect rect(width1 + width2, 0, width3, this->height()); painter->drawRect(rect); //繪製文字 if (showValue) { //設置文字字體+顏色 if (autoFont) { QFont font; font.setPixelSize(this->height() * 0.9); painter->setFont(font); } QString text = QString::number(value3); if (showPercent) { text = QString("%1%").arg(QString::number(percent * 100, 'f', 0)); } painter->setPen(textColor); painter->drawText(rect, Qt::AlignCenter, text); } painter->restore(); } void ProgressThree::drawBorder(QPainter *painter) { painter->save(); QPen pen; pen.setWidthF(borderWidth); pen.setColor(borderColor); painter->setPen(borderWidth > 0 ? pen : Qt::NoPen); painter->setBrush(Qt::NoBrush); int radius = this->radius; if (autoRadius) { radius = this->height() / 2; } //繪製圓角矩形 painter->drawRoundedRect(this->rect(), radius, radius); painter->restore(); }