服务器之家

服务器之家 > 正文

Qt 进度条的实现示例

时间:2021-11-11 15:40     来源/作者:凉天满月

一、前言

  有时我们需要在表格(QTableWidget)、树状栏(QTreeWidget)中直观显示任务进度或消耗百分比,达到报表显示的形式,可通过重写QLabel的方式实现。

  1、进度条控件功能

    1)可设置值动态变化

    2)可设置警戒值

    3)可设置正常颜色和报警颜色

    4)可设置边框渐变颜色

    5)可设置变化时每次移动的步长

    6)可设置错误时显示错误描述

    7)可设置显示值保留小数的位数

    8)可设置边框圆角角度/背景进度圆角角度/头部圆角角度    

  2、实现效果

  Qt 进度条的实现示例

二、实现过程

  1、运行环境Qt5.5 VS2013

  2、继承QLabel重写ProgressLabel控件

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

  3、重写paintEvent事件,根据是否有出错,绘制出错信息或值

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

  4、刷新值时采用定时器定时刷新方式,达到动态效果

创建定时器

?
1
2
3
timer = new QTimer(this);
timer->setInterval(10);
connect(timer, SIGNAL(timeout()), this, SLOT(updateValue()));

按step值刷新

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
void ProgressLabel::updateValue()
 {
     if (isForward)
     {
         currentValue -= step;
 
         if (currentValue <= value)
         {
             timer->stop();
            currentValue = value;//保持真实性
        }
    }
    else
    {
        currentValue += step;
 
        if (currentValue >= value)
        {
            timer->stop();
            currentValue = value;//保持真实性
        }
    }
 
    this->update();
}

  5、外部设置值的时候,清除错误标志,并启动定时器

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

到此这篇关于Qt 进度条的实现示例的文章就介绍到这了,更多相关Qt 进度条内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://www.cnblogs.com/liangtianmanyue/p/14827714.html

标签:

相关文章

热门资讯

yue是什么意思 网络流行语yue了是什么梗
yue是什么意思 网络流行语yue了是什么梗 2020-10-11
2020微信伤感网名听哭了 让对方看到心疼的伤感网名大全
2020微信伤感网名听哭了 让对方看到心疼的伤感网名大全 2019-12-26
背刺什么意思 网络词语背刺是什么梗
背刺什么意思 网络词语背刺是什么梗 2020-05-22
2021年耽改剧名单 2021要播出的59部耽改剧列表
2021年耽改剧名单 2021要播出的59部耽改剧列表 2021-03-05
苹果12mini价格表官网报价 iPhone12mini全版本价格汇总
苹果12mini价格表官网报价 iPhone12mini全版本价格汇总 2020-11-13
返回顶部