QT版本:win32 QT Creator5.9.9
在QT中只有橫條狀的進度條,目前需要使用圓形狀進度條顯示進度,只能自己設計一個,可以顯示圓弧、圓圈和中心文本。
設計思路:
①設計一個QWidget部件類。
提供圓圈的半徑屬性,根據該屬性把該部件初始化為一個長寬相等的正方形部件。
②重載painterEvent()事件。
③在painterEvent事件中定義一個畫家、畫筆、字體對象,使用drawArc接口繪制圓弧和drawText接口繪制中心文本,最后更新部件。
a、設計時提供畫筆、文本類的設置接口,用於設置圓圈和字體的模樣,繪制圓時占滿窗體,繪制圓弧時要根據圓的路徑寬度重新獲取半徑,防止超出窗體;框定文本的位置,固定范圍和居中顯示;drawArc方法繪制的圓存在諸多毛刺,需要更改渲染模式。
b、drawArc方法默認是從3點鍾方向呈逆時針繪制的,要設計方法固定為0點鍾起始,進度方向可調。
④針對上一步為整個工程提供設置接口。
⑤在使用時,與QTimeLine類時間軸結合使用,可以達到動態顯示的結果。
待優化:
添加進度條背景
進度條顏色漸變
餅狀顯示
實驗結果:
在使用時可以更改顏色和形狀大小,邊線大小和文本樣式;把該部件動作子部件時,標題框不存在,且背景色為透明色。
代碼實現:
arcPainter.h:
1 #ifndef ARCPAINT_H 2 #define ARCPAINT_H 3 4 #include <QWidget> 5 #include <QPen> 6 #include <QPainter> 7 #include <QDebug> 8 #include <QLabel> 9 #include <QLayout> 10 #include <QHBoxLayout> 11 #include <QVBoxLayout> 12 #include <QFont> 13 #include <QTimeLine> 14 #include <QMouseEvent> 15 #include <QTimerEvent> 16 17 class ArcPaint : public QWidget 18 { 19 Q_OBJECT 20 public: 21 enum Direction {clockwise = -1, anticlockwise = 1}; 22 ArcPaint(QWidget *parent = nullptr); 23 ~ArcPaint(); 24 void setRadius(int val); //設置半徑 25 //設置文本 26 void setCenterText(const QString &str); // 字符串 27 void setCenterText(int val, const QString &catStr = NULL); // 數字 28 void setCenterText(double val, const QString &catStr = NULL, int precision = 2); 29 // 設置弧線 30 void setArcAngle(int angle, Direction direction = clockwise); // 默認方向逆時針 31 // 獲取畫家相關參數 32 QPen * getPen(); 33 QFont * getFont(); 34 protected: 35 void paintEvent(QPaintEvent *event); // 重載繪畫事件 36 37 private: 38 double percent; // 進度百分比,與current相互影響 39 int radius; // 半徑大小 40 int arcRangle; 41 QPen * arcPen; 42 QFont * font; 43 QPainter * painter; 44 QString text; 45 }; 46 #endif // ARCPAINT_H
arcPainter.cpp:
1 #include "arcpaint.h" 2 3 ArcPaint::ArcPaint(QWidget *parent) 4 : QWidget(parent) 5 { 6 radius = 100; 7 arcRangle = 180; 8 this->resize(radius*2, radius*2); 9 painter = new QPainter(); 10 11 arcPen = new QPen; 12 arcPen->setColor(Qt::blue); 13 arcPen->setStyle(Qt::SolidLine); 14 arcPen->setCapStyle(Qt::RoundCap); 15 arcPen->setJoinStyle(Qt::RoundJoin); 16 17 arcPen->setWidthF(10.0); 18 19 font = new QFont(); 20 font->setPixelSize(30); 21 22 text = "H"; 23 } 24 25 ArcPaint::~ArcPaint() 26 { 27 delete font; 28 delete arcPen; 29 delete painter; 30 } 31 32 void ArcPaint::setRadius(int val) 33 { 34 radius = val; 35 this->resize(radius*2, radius*2); 36 } 37 void ArcPaint::setCenterText(const QString &str) 38 { 39 text = str; 40 } 41 42 void ArcPaint::setCenterText(int val, const QString &catStr) 43 { 44 text = text.setNum(val) + catStr; 45 } 46 47 void ArcPaint::setCenterText(double val, const QString &catStr, int precision) 48 { 49 text = text.setNum(val, 'f', precision) + catStr; 50 } 51 52 void ArcPaint::setArcAngle(int angle, Direction direction) 53 { 54 arcRangle = angle * direction; 55 } 56 57 void ArcPaint::paintEvent(QPaintEvent *event) 58 { 59 painter->begin(this); 60 // 設置渲染模式 61 painter->setRenderHint(QPainter::HighQualityAntialiasing, true); 62 // 設置畫筆 63 painter->setPen(*arcPen); 64 // 設置文本格式 65 painter->setFont(*font); 66 // 設置文本顯示范圍 67 QRect textRect(0,0,this->width(), this->height()); 68 // 繪制文本,在范圍內居中顯示 69 painter->drawText(textRect, Qt::AlignCenter, text); 70 71 int penW = arcPen->width(); 72 // 繪制圓弧 73 painter->drawArc((penW)/2,penW/2,radius*2-penW,radius*2-penW,90*16,arcRangle*16); 74 75 painter->end(); 76 this->update(); 77 } 78 79 QPen *ArcPaint::getPen() 80 { 81 return arcPen; 82 } 83 84 QFont *ArcPaint::getFont() 85 { 86 return font; 87 }
main.cpp:
1 #include "arcpaint.h" 2 3 #include <QApplication> 4 5 int main(int argc, char *argv[]) 6 { 7 QApplication a(argc, argv); 8 ArcPaint w; 9 w.setArcAngle(60, ArcPaint::anticlockwise); 10 w.setCenterText(60, "°"); 11 w.show(); 12 return a.exec(); 13 }