欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Qt 进度条

程序员文章站 2022-01-07 09:48:24
一、前言 有时我们需要在表格(QTableWidget)、树状栏(QTreeWidget)中直观显示任务进度或消耗百分比,达到报表显示的形式,可通过重写QLabel的方式实现。 1、进度条控件功能 1)可设置值动态变化 2)可设置警戒值 3)可设置正常颜色和报警颜色 4)可设置边框渐变颜色 5)可设 ......

一、前言

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

  1、进度条控件功能

    1)可设置值动态变化

    2)可设置警戒值

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

    4)可设置边框渐变颜色

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

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

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

    8)可设置边框圆角角度/背景进度圆角角度/头部圆角角度    
  2、实现效果

  Qt 进度条

二、实现过程

  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

  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 gradient(qpointf(0, 0), qpointf(0, height()));
21         if (currentvalue >= alarmvalue)
22         {
23             gradient.setcolorat(0.0, alarmcolorstart);
24             gradient.setcolorat(1.0, alarmcolorend);
25         }
26         else
27         {
28             gradient.setcolorat(0.0, normalcolorstart);
29             gradient.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(gradient);
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 }

  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 }