image.png

instrumentpanel.h

  1. #ifndef INSTRUMENTPANEL_H
  2. #define INSTRUMENTPANEL_H
  3. #include <QWidget>
  4. #include <QTimer>
  5. namespace Ui {
  6. class InstrumentPanel;
  7. }
  8. class InstrumentPanel : public QWidget
  9. {
  10. Q_OBJECT
  11. public:
  12. explicit InstrumentPanel(QWidget *parent = 0);
  13. ~InstrumentPanel();
  14. private:
  15. Ui::InstrumentPanel *ui;
  16. protected:
  17. void paintEvent(QPaintEvent *);
  18. void drawCrown(QPainter *painter);
  19. void drawBackground(QPainter *painter);
  20. void drawScale(QPainter *painter);
  21. void drawScaleNum(QPainter *painter);
  22. void drawTitle(QPainter *painter);
  23. void drawIndicator(QPainter *painter);
  24. void drawNumericValue(QPainter *painter);
  25. private:
  26. QColor m_background;
  27. QColor m_foreground;
  28. int m_maxValue;
  29. int m_minValue;
  30. int m_startAngle;
  31. int m_endAngle;
  32. int m_scaleMajor;
  33. int m_scaleMinor;
  34. double m_value;
  35. int m_precision;
  36. QTimer *m_updateTimer;
  37. QString m_units;
  38. QString m_title;
  39. public Q_SLOTS:
  40. // void UpdateAngle();
  41. public:
  42. void UpdatePanelVal(double); // 用于外部设置仪表盘的值
  43. };
  44. #endif // INSTRUMENTPANEL_H

instrumentpanel.c

  1. #include "instrumentpanel.h"
  2. #include "ui_instrumentpanel.h"
  3. #include <QPainter>
  4. InstrumentPanel::InstrumentPanel(QWidget *parent) :
  5. QWidget(parent),
  6. ui(new Ui::InstrumentPanel)
  7. {
  8. ui->setupUi(this);
  9. // 8.构造函数的初始化
  10. m_background = Qt::black;
  11. m_foreground = Qt::green;
  12. m_startAngle = 60;
  13. m_endAngle = 60;
  14. m_scaleMajor = 10;
  15. m_minValue = -50;
  16. m_maxValue = 50;
  17. m_scaleMajor = 10;//分度
  18. m_scaleMinor = 10;
  19. m_units = "km/h";
  20. m_title = "Speed Meter";
  21. m_precision = 0;
  22. m_value = 0;
  23. m_updateTimer = new QTimer(this);
  24. m_updateTimer->setInterval(50);//间隔,微妙微单位,大家可以改一下这个值看看转动速度。
  25. // connect(m_updateTimer, SIGNAL(timeout()), this, SLOT(UpdateAngle()));
  26. // m_updateTimer->start();//启动定时器
  27. setWindowFlags(Qt::FramelessWindowHint);//无窗体
  28. setAttribute(Qt::WA_TranslucentBackground);//背景透明
  29. resize(400, 400);
  30. }
  31. InstrumentPanel::~InstrumentPanel()
  32. {
  33. delete ui;
  34. }
  35. // 1.绘制表冠
  36. void InstrumentPanel::drawCrown(QPainter *painter) //绘制表冠
  37. {
  38. painter->save();
  39. int radius = 100;
  40. QLinearGradient lg1(0, -radius, 0, radius);
  41. lg1.setColorAt(0, Qt::white); //设置渐变的颜色和路径比例
  42. lg1.setColorAt(1, Qt::gray); //只是粗略的颜色,具体的可以参考RGB颜色查询对照表
  43. painter->setBrush(lg1); // 创建QBrush对象,把这个渐变对象传递进去:
  44. painter->setPen(Qt::NoPen); //边框线无色
  45. painter->drawEllipse(-radius, -radius, radius << 1, radius << 1);
  46. painter->setBrush(m_background = Qt::black);
  47. painter->drawEllipse(-92, -92, 184, 184);
  48. painter->restore();
  49. }
  50. // 2.绘制刻度值
  51. void InstrumentPanel::drawScaleNum(QPainter *painter) //绘制刻度数字
  52. {
  53. painter->save();
  54. painter->setPen(m_foreground);
  55. //m_startAngle是起始角度,m_endAngle是结束角度,m_scaleMajor在一个量程中分成的刻度数
  56. double startRad = ( 270 - m_startAngle) * (3.14 / 180);
  57. double deltaRad = (360 - m_startAngle - m_endAngle) * (3.14 / 180) / m_scaleMajor;
  58. double sina,cosa;
  59. int x, y;
  60. QFontMetricsF fm(this->font());
  61. double w, h, tmpVal;
  62. QString str;
  63. for (int i = 0; i <= m_scaleMajor; i++)
  64. {
  65. sina = sin(startRad - i * deltaRad);
  66. cosa = cos(startRad - i * deltaRad);
  67. tmpVal = 1.0 * i *((m_maxValue - m_minValue) / m_scaleMajor) + m_minValue;
  68. // tmpVal = 50;
  69. str = QString( "%1" ).arg(tmpVal); //%1作为占位符 arg()函数比起 sprintf()来是类型安全的
  70. w = fm.size(Qt::TextSingleLine,str).width();
  71. h = fm.size(Qt::TextSingleLine,str).height();
  72. x = 82 * cosa - w / 2;
  73. y = -82 * sina + h / 4;
  74. painter->drawText(x, y, str); //函数的前两个参数是显示的坐标位置,后一个是显示的内容,是字符类型""
  75. }
  76. painter->restore();
  77. }
  78. // 3.绘制刻度线
  79. void InstrumentPanel::drawScale(QPainter *painter) //绘制刻度线
  80. {
  81. painter->save();
  82. painter->rotate(m_startAngle);
  83. int steps = (m_scaleMajor * m_scaleMinor); //相乘后的值是分的份数
  84. double angleStep = (360.0 - m_startAngle - m_endAngle) / steps; //每一个份数的角度
  85. // painter->setPen(m_foreground); //m_foreground是颜色的设置
  86. // QPen pen = painter->pen(); //第一种方法
  87. QPen pen ;
  88. pen.setColor(Qt::green); //推荐使用第二种方式
  89. for (int i = 0; i <= steps; i++)
  90. {
  91. if (i % m_scaleMinor == 0)//整数刻度显示加粗
  92. {
  93. pen.setWidth(1); //设置线宽
  94. painter->setPen(pen); //使用面向对象的思想,把画笔关联上画家。通过画家画出来
  95. painter->drawLine(0, 62, 0, 72); //两个参数应该是两个坐标值
  96. }
  97. else
  98. {
  99. pen.setWidth(0);
  100. painter->setPen(pen);
  101. painter->drawLine(0, 67, 0, 72);
  102. }
  103. painter->rotate(angleStep);
  104. }
  105. painter->restore();
  106. }
  107. // 4.绘制标题
  108. void InstrumentPanel::drawTitle(QPainter *painter)
  109. {
  110. painter->save();
  111. painter->setPen(m_foreground);
  112. //painter->setBrush(m_foreground);
  113. QString str(m_title); //显示仪表的功能
  114. QFontMetricsF fm(this->font());
  115. double w = fm.size(Qt::TextSingleLine,str).width();
  116. painter->drawText(-w / 2, -30, str);
  117. painter->restore();
  118. }
  119. // 5.显示的单位,与数值
  120. void InstrumentPanel::drawNumericValue(QPainter *painter)
  121. {
  122. QString str = QString("%1 %2").arg(m_value, 0, 'f', m_precision).arg(m_units);
  123. QFontMetricsF fm(font());
  124. double w = fm.size(Qt::TextSingleLine,str).width();
  125. painter->setPen(m_foreground);
  126. painter->drawText(-w / 2, 42, str);
  127. }
  128. // 6.绘制表针,和中心点
  129. void InstrumentPanel::drawIndicator(QPainter *painter)
  130. {
  131. painter->save();
  132. QPolygon pts;
  133. pts.setPoints(3, -2, 0, 2, 0, 0, 60); /* (-2,0)/(2,0)/(0,60) *///第一个参数是 ,坐标的个数。后边的是坐标
  134. painter->rotate(m_startAngle);
  135. double degRotate = (360.0 - m_startAngle - m_endAngle) / (m_maxValue - m_minValue)*(m_value - m_minValue);
  136. //画指针
  137. painter->rotate(degRotate); //顺时针旋转坐标系统
  138. QRadialGradient haloGradient(0, 0, 60, 0, 0); //辐射渐变
  139. haloGradient.setColorAt(0, QColor(60, 60, 60));
  140. haloGradient.setColorAt(1, QColor(160, 160, 160)); //灰
  141. painter->setPen(Qt::white); //定义线条文本颜色 设置线条的颜色
  142. painter->setBrush(haloGradient); //刷子定义形状如何填满 填充后的颜色
  143. painter->drawConvexPolygon(pts); //这是个重载函数,绘制多边形。
  144. painter->restore();
  145. //画中心点
  146. QColor niceBlue(150, 150, 200);
  147. QConicalGradient coneGradient(0, 0, -90.0); //角度渐变
  148. coneGradient.setColorAt(0.0, Qt::darkGray);
  149. coneGradient.setColorAt(0.2, niceBlue);
  150. coneGradient.setColorAt(0.5, Qt::white);
  151. coneGradient.setColorAt(1.0, Qt::darkGray);
  152. painter->setPen(Qt::NoPen); //没有线,填满没有边界
  153. painter->setBrush(coneGradient);
  154. painter->drawEllipse(-5, -5, 10, 10);
  155. }
  156. // 7.重绘函数
  157. void InstrumentPanel::paintEvent(QPaintEvent *)
  158. {
  159. QPainter painter(this);//一个类中的this表示一个指向该类自己的指针
  160. painter.setRenderHint(QPainter::Antialiasing); /* 使用反锯齿(如果可用) */
  161. painter.translate(width() / 2, height() / 2); /* 坐标变换为窗体中心 */
  162. int side = qMin(width(), height());
  163. painter.scale(side / 200.0, side / 200.0); /* 比例缩放 */
  164. drawCrown(&painter); /* 画表盘边框 */
  165. drawScaleNum(&painter); /* 画刻度数值值 */
  166. drawScale(&painter); /* 画刻度线 */
  167. drawTitle(&painter); /* 画单位 */
  168. drawNumericValue(&painter); /* 画数字显示 */
  169. drawIndicator(&painter); /* 画表针 */
  170. }
  171. // 更新仪表盘
  172. void InstrumentPanel::UpdatePanelVal(double num)
  173. {
  174. m_value = num;
  175. update();
  176. }

mainwindow.h

  1. #ifndef MAINWINDOW_H
  2. #define MAINWINDOW_H
  3. #include <QMainWindow>
  4. #include "instrumentpanel.h"
  5. namespace Ui {
  6. class MainWindow;
  7. }
  8. class MainWindow : public QMainWindow
  9. {
  10. Q_OBJECT
  11. public:
  12. explicit MainWindow(QWidget *parent = 0);
  13. ~MainWindow();
  14. private slots:
  15. void on_pushButton_clicked();
  16. private:
  17. Ui::MainWindow *ui;
  18. private:
  19. InstrumentPanel *instrumentpanel1;
  20. InstrumentPanel *instrumentpanel2;
  21. InstrumentPanel *instrumentpanel3;
  22. };
  23. #endif // MAINWINDOW_H

mainwindow.c

  1. #include "mainwindow.h"
  2. #include "ui_mainwindow.h"
  3. MainWindow::MainWindow(QWidget *parent) :
  4. QMainWindow(parent),
  5. ui(new Ui::MainWindow)
  6. {
  7. ui->setupUi(this);
  8. // 创建三个仪表盘类
  9. instrumentpanel1 = new InstrumentPanel(this);
  10. instrumentpanel2 = new InstrumentPanel(this);
  11. instrumentpanel3 = new InstrumentPanel(this);
  12. // 将三个仪表盘加载到窗口上
  13. ui->verticalLayout1->addWidget(instrumentpanel1);
  14. ui->verticalLayout2->addWidget(instrumentpanel2);
  15. ui->verticalLayout3->addWidget(instrumentpanel3);
  16. }
  17. MainWindow::~MainWindow()
  18. {
  19. delete ui;
  20. }
  21. void MainWindow::on_pushButton_clicked()
  22. {
  23. double num = ui->lineEdit->text().toDouble();
  24. instrumentpanel1->UpdatePanelVal(num);
  25. }

文件压缩包:ZG_Project.zip

参考资料:https://blog.csdn.net/Aidam_Bo/article/details/85266798
其他参考资料:
Qt编写自定义控件1-汽车仪表盘
Qt编写自定义控件21-圆弧仪表盘