Qt 进度条
程序员文章站
2022-06-10 13:56:44
一、前言 有时我们需要在表格(QTableWidget)、树状栏(QTreeWidget)中直观显示任务进度或消耗百分比,达到报表显示的形式,可通过重写QLabel的方式实现。 1、进度条控件功能 1)可设置值动态变化 2)可设置警戒值 3)可设置正常颜色和报警颜色 4)可设置边框渐变颜色 5)可设 ......
一、前言
有时我们需要在表格(qtablewidget)、树状栏(qtreewidget)中直观显示任务进度或消耗百分比,达到报表显示的形式,可通过重写qlabel的方式实现。
1、进度条控件功能
1)可设置值动态变化
2)可设置警戒值
3)可设置正常颜色和报警颜色
4)可设置边框渐变颜色
5)可设置变化时每次移动的步长
6)可设置错误时显示错误描述
7)可设置显示值保留小数的位数
8)可设置边框圆角角度/背景进度圆角角度/头部圆角角度
2、实现效果
二、实现过程
1、运行环境qt5.5 vs2013
2、继承qlabel重写progresslabel控件
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事件,根据是否有出错,绘制出错信息或值
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、刷新值时采用定时器定时刷新方式,达到动态效果
1 timer = new qtimer(this); 2 timer->setinterval(10); 3 connect(timer, signal(timeout()), this, slot(updatevalue()));
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、外部设置值的时候,清除错误标志,并启动定时器
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 }