Qt 進度條

涼天滿月發表於2021-05-30

一、前言

  有時我們需要在表格(QTableWidget)、樹狀欄(QTreeWidget)中直觀顯示任務進度或消耗百分比,達到報表顯示的形式,可通過重寫QLabel的方式實現。

  1、進度條控制元件功能

    1)可設定值動態變化

    2)可設定警戒值

    3)可設定正常顏色和報警顏色

    4)可設定邊框漸變顏色

    5)可設定變化時每次移動的步長

    6)可設定錯誤時顯示錯誤描述

    7)可設定顯示值保留小數的位數

    8)可設定邊框圓角角度/背景進度圓角角度/頭部圓角角度    
  2、實現效果

  

二、實現過程

  1、執行環境Qt5.5 VS2013

  2、繼承QLabel重寫ProgressLabel控制元件

Qt 進度條
  1 /***********************************************************************
  2 作者:liangtianmanyue(QQ:1660941209) 2021-05-30
  3 功能:進度控制元件
  4 1、可設定值動態變化
  5 2、可設定警戒值
  6 3、可設定正常顏色和報警顏色
  7 4、可設定邊框漸變顏色
  8 5、可設定變化時每次移動的步長
  9 6、可設定錯誤時顯示錯誤描述
 10 6、可設定顯示值保留小數的位數
 11 8、可設定邊框圓角角度/背景進度圓角角度/頭部圓角角度
 12 ************************************************************************/
 13 
 14 #ifndef PROGRESS_LABEL_H
 15 #define PROGRESS_LABEL_H
 16 
 17 #include <QLabel>
 18 #include <QWidget>
 19 
 20 #ifdef Plugin
 21 #if (QT_VERSION < QT_VERSION_CHECK(5,7,0))
 22 #include <QtDesigner/QDesignerExportWidget>
 23 #else
 24 #include <QtUiPlugin/QDesignerExportWidget>
 25 #endif
 26 
 27 class QDESIGNER_WIDGET_EXPORT ProgressLabel : public QLabel
 28 #else
 29 class ProgressLabel : public QLabel
 30 #endif
 31 {
 32     Q_OBJECT    
 33     Q_PROPERTY(double minValue READ getMinValue WRITE setMinValue)
 34     Q_PROPERTY(double maxValue READ getMaxValue WRITE setMaxValue)
 35     Q_PROPERTY(double value READ getValue WRITE setValue)
 36     Q_PROPERTY(double alarmValue READ getAlarmValue WRITE setAlarmValue)
 37 
 38     Q_PROPERTY(double step READ getStep WRITE setStep)
 39     Q_PROPERTY(int decimals READ getDecimals WRITE setDecimals)
 40     Q_PROPERTY(int borderRadius READ getBorderRadius WRITE setBorderRadius)
 41     Q_PROPERTY(int bgRadius READ getBgRadius WRITE setBgRadius)
 42     Q_PROPERTY(int headRadius READ getHeadRadius WRITE setHeadRadius)
 43 
 44     Q_PROPERTY(QColor borderColorStart READ getBorderColorStart WRITE setBorderColorStart)
 45     Q_PROPERTY(QColor borderColorEnd READ getBorderColorEnd WRITE setBorderColorEnd)
 46 
 47     Q_PROPERTY(QColor alarmColorStart READ getAlarmColorStart WRITE setAlarmColorStart)
 48     Q_PROPERTY(QColor alarmColorEnd READ getAlarmColorEnd WRITE setAlarmColorEnd)
 49 
 50     Q_PROPERTY(QColor normalColorStart READ getNormalColorStart WRITE setNormalColorStart)
 51     Q_PROPERTY(QColor normalColorEnd READ getNormalColorEnd WRITE setNormalColorEnd)
 52 
 53 public:
 54     explicit ProgressLabel(QWidget *parent = 0);
 55     ~ProgressLabel();
 56 
 57 protected:
 58     void paintEvent(QPaintEvent *);
 59     void drawBg(QPainter *painter);
 60 
 61 private slots:
 62     void updateValue();
 63 
 64 public:    
 65     double getMinValue()            const;
 66     double getMaxValue()            const;
 67     double getValue()               const;
 68     double getAlarmValue()          const;
 69 
 70     double getStep()                const;
 71     int getBorderRadius()           const;
 72     int getBgRadius()               const;
 73     int getHeadRadius()             const;
 74 
 75     QColor getBorderColorStart()    const;
 76     QColor getBorderColorEnd()      const;
 77 
 78     QColor getAlarmColorStart()     const;
 79     QColor getAlarmColorEnd()       const;
 80 
 81     QColor getNormalColorStart()    const;
 82     QColor getNormalColorEnd()      const;
 83 
 84     QSize sizeHint()                const;
 85     QSize minimumSizeHint()         const;
 86 
 87 public Q_SLOTS:
 88     //設定範圍值
 89     void setRange(double minValue, double maxValue);
 90     void setRange(int minValue, int maxValue);
 91 
 92     //設定最大最小值
 93     void setMinValue(double minValue);
 94     void setMaxValue(double maxValue);
 95 
 96     //設定顯示值
 97     void setValue(double value);
 98     void setValue(int value);
 99 
100     //設定警戒值
101     void setAlarmValue(double alarmValue);
102     void setAlarmValue(int alarmValue);
103 
104     //設定步長
105     void setStep(double step);
106     void setStep(int step);
107 
108     //小數點位數
109     int getDecimals();
110     void setDecimals(int decimals);
111 
112     //設定邊框圓角角度
113     void setBorderRadius(int borderRadius);
114     //設定背景圓角角度
115     void setBgRadius(int bgRadius);
116     //設定頭部圓角角度
117     void setHeadRadius(int headRadius);
118 
119     //設定邊框漸變顏色
120     void setBorderColorStart(const QColor &borderColorStart);
121     void setBorderColorEnd(const QColor &borderColorEnd);
122 
123     //設定報警時的漸變顏色
124     void setAlarmColorStart(const QColor &alarmColorStart);
125     void setAlarmColorEnd(const QColor &alarmColorEnd);
126 
127     //設定正常時的漸變顏色
128     void setNormalColorStart(const QColor &normalColorStart);
129     void setNormalColorEnd(const QColor &normalColorEnd);
130     
131     //正常、異常顯示
132     void setNormalState();
133     void setErrorText(const QString &text);
134 
135 Q_SIGNALS:
136     void valueChanged(double value);
137 
138 private:
139     bool m_IsError;                 //是否出錯
140     QString m_ErrorText;            //錯誤描述
141 
142     double minValue;                //最小值
143     double maxValue;                //最大值
144     double value;                   //目標電量
145     double alarmValue;              //警戒值
146     int decimals;                   //顯示小數點後位數
147     double step;                    //每次移動的步長
148     int borderRadius;               //邊框圓角角度
149     int bgRadius;                   //背景進度圓角角度
150     int headRadius;                 //頭部圓角角度
151 
152     QColor borderColorStart;        //邊框漸變開始顏色
153     QColor borderColorEnd;          //邊框漸變結束顏色
154 
155     QColor alarmColorStart;         //超警戒值時的漸變開始顏色
156     QColor alarmColorEnd;           //超警戒值時的漸變結束顏色
157 
158     QColor normalColorStart;        //正常時的漸變開始顏色
159     QColor normalColorEnd;          //正常時的漸變結束顏色
160 
161     bool isForward;                 //是否往前移
162     double currentValue;            //當前值
163     QRectF mainRect;                //主體區域
164     QTimer *timer;                  //繪製定時器
165 };
166 
167 #endif // PROGRESS_LABEL_H
ProgressLabel定義

  3、重寫paintEvent事件,根據是否有出錯,繪製出錯資訊或值

Qt 進度條
 1 void ProgressLabel::paintEvent(QPaintEvent *)
 2 {
 3     //繪製準備工作,啟用反鋸齒
 4     QPainter painter(this);
 5     painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
 6 
 7     //獲取邊框區域
 8     QPointF topLeft(2, 2);
 9     QPointF bottomRight(width() - 4, height() - 2);
10     mainRect = QRectF(topLeft, bottomRight);
11     //繪製背景
12     drawBg(&painter);
13 }
14 
15 void ProgressLabel::drawBg(QPainter *painter)
16 {
17     if(!m_IsError)
18     {
19         painter->save();
20         QLinearGradient batteryGradient(QPointF(0, 0), QPointF(0, height()));
21         if (currentValue >= alarmValue)
22         {
23             batteryGradient.setColorAt(0.0, alarmColorStart);
24             batteryGradient.setColorAt(1.0, alarmColorEnd);
25         }
26         else
27         {
28             batteryGradient.setColorAt(0.0, normalColorStart);
29             batteryGradient.setColorAt(1.0, normalColorEnd);
30         }
31 
32         double min = qMin(width(), height());
33         int margin =  min / 20;
34         double unit = (mainRect.width() - (margin * 2)) / 100;
35         double width = currentValue * unit;
36         QPointF topLeft(mainRect.topLeft().x() + margin, mainRect.topLeft().y() + margin);
37         QPointF bottomRight(width + margin + 5, mainRect.bottomRight().y() - margin);
38         QRectF rect(topLeft, bottomRight);
39 
40         painter->setPen(Qt::NoPen);
41         painter->setBrush(batteryGradient);
42         painter->drawRoundedRect(rect, bgRadius, bgRadius);
43         painter->restore();
44     }
45 
46     //寫進度
47     painter->save();
48     QPen pen(Qt::SolidLine);
49     pen.setWidth(1);
50     if(m_IsError)
51         pen.setColor(Qt::red);
52     else
53         pen.setColor(Qt::black);    
54     painter->setPen(pen);
55     painter->setBrush(Qt::NoBrush);
56     if(m_IsError)
57         painter->drawText(mainRect, Qt::AlignCenter, m_ErrorText);
58     else 
59         painter->drawText(mainRect, Qt::AlignCenter, QString("%1%").arg(currentValue, 0, 'f', decimals));
60     painter->restore();
61 }
控制元件繪製

  4、重新整理值時採用定時器定時重新整理方式,達到動態效果

Qt 進度條
1 timer = new QTimer(this);
2 timer->setInterval(10);
3 connect(timer, SIGNAL(timeout()), this, SLOT(updateValue()));
建立定時器
Qt 進度條
 1 void ProgressLabel::updateValue()
 2 {
 3     if (isForward)
 4     {
 5         currentValue -= step;
 6 
 7         if (currentValue <= value)
 8         {
 9             timer->stop();
10             currentValue = value;//保持真實性
11         }
12     } 
13     else
14     {
15         currentValue += step;
16 
17         if (currentValue >= value)
18         {
19             timer->stop();
20             currentValue = value;//保持真實性
21         }
22     }
23 
24     this->update();
25 }
按step值重新整理

  5、外部設定值的時候,清除錯誤標誌,並啟動定時器

Qt 進度條
 1 void ProgressLabel::setValue(double value)
 2 {
 3     m_IsError = false;
 4     //值和當前值一致則無需處理
 5     if (value == this->value)
 6         return;
 7 
 8     //值小於最小值則取最小值,大於最大值則取最大值
 9     if (value < minValue)
10         value = minValue;
11     else if (value > maxValue)
12         value = maxValue;
13 
14     if (value > currentValue)
15         isForward = false;
16     else if (value < currentValue)
17         isForward = true;
18     else
19         return;
20 
21     this->value = value;
22     this->update();
23     emit valueChanged(value);
24     timer->start();
25 }
設定值

 

相關文章