• QPaint绘制自定义仪表盘组件03


    网上视频抄的,用来自己看一下,看完就删掉

    ui

     mainwindow.h

    1. #ifndef MAINWINDOW_H
    2. #define MAINWINDOW_H
    3. #include
    4. #include
    5. #include
    6. #include
    7. #include
    8. #include
    9. #include
    10. #include
    11. #include
    12. #include
    13. QT_BEGIN_NAMESPACE
    14. namespace Ui { class MainWindow; }
    15. QT_END_NAMESPACE
    16. class MainWindow : public QMainWindow
    17. {
    18. Q_OBJECT
    19. public:
    20. MainWindow(QWidget *parent = nullptr);
    21. ~MainWindow();
    22. QTimer *myTimer;
    23. int radius;//仪表盘的中心位置
    24. int direction;//指针运动的方向,1为前进,0为后退
    25. protected:
    26. void paintEvent(QPaintEvent*);
    27. private:
    28. int degRotate =0;
    29. private:
    30. void DrawPoint(QPainter&,int);
    31. void DrawDigital(QPainter&,int);
    32. void DrawCircle(QPainter&,int);
    33. void DrawSmallScale(QPainter&,int);
    34. void DrawBigScale(QPainter&,int);
    35. void DrawUnit(QPainter&,int);
    36. void DrawNum(QPainter&,int);
    37. void DrawPointer(QPainter&,int);
    38. void drawIndicator(QPainter *painter);
    39. void DrawCircle_line(QPainter& painter,int radius);
    40. void DrawCircle_bom(QPainter& painter,int radius);
    41. void DrawCircle_bom_big(QPainter& painter,int radius);
    42. void DrawCircle_bom_shine(QPainter& painter,int radius);
    43. void DrawCircle_bom_small(QPainter& painter,int radius);
    44. void DrawCircle_arc(QPainter& painter,int radius);
    45. void keyPressEvent(QKeyEvent *event);
    46. void keyReleaseEvent(QKeyEvent *event);
    47. private slots:
    48. void slot_speed_changed();
    49. private:
    50. Ui::MainWindow *ui;
    51. };
    52. #endif // MAINWINDOW_H

     mainwindow.cpp

    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. // setFixedSize() 函数是 QWidget 类的一个成员函数,用于设置窗口的固定大小。
    9. // 该函数接受两个参数,分别是窗口宽度和高度。
    10. // 设置后无法通过拖拽窗口的边缘来改变窗口大小,而且,即使添加的控件超出了窗口大小,也不会出现滚动条。
    11. setFixedSize(1280,800);
    12. //定时器动态增加时速
    13. myTimer = new QTimer(this);
    14. connect(myTimer,SIGNAL(timeout()),this,SLOT(slot_speed_changed()));
    15. }
    16. void MainWindow::paintEvent(QPaintEvent*)
    17. {
    18. QPainter painter(this);
    19. int width=this->width();
    20. int height=this->height() - 100;//移动仪表盘的高度
    21. int radius=((width>height)?height:width)/2.0;//仪表盘的中心位置
    22. //移动画笔到中下方
    23. painter.translate(width/2,height*0.6);
    24. //启用反锯齿
    25. painter.setRenderHint(QPainter::Antialiasing, true);
    26. painter.setPen(Qt::NoPen);
    27. //设置画刷颜色
    28. painter.setBrush(QColor(138,43,226));
    29. DrawSmallScale(painter,radius-60);//刻度线
    30. DrawDigital(painter,radius-90);//刻度数字
    31. /*所有形状绘画*/
    32. // DrawCircle_bom(painter,radius-40); //扇形大圆
    33. DrawCircle(painter,radius-35); //渐变发光外扇形
    34. DrawCircle_arc(painter,radius - 40);//动态扇形环
    35. DrawPointer(painter,radius-130);//指针
    36. DrawCircle_line(painter,radius-35); //最外细圆线
    37. DrawCircle_bom_big(painter,radius-150);//中间大圆
    38. DrawCircle_bom_shine(painter,radius - 230);//渐变发光内圈
    39. DrawCircle_bom_small(painter,radius - 200);//中间小圆
    40. DrawUnit(painter,radius - 390);//单位
    41. DrawNum(painter,radius-300);//时速
    42. }
    43. //绘制外圈点
    44. void MainWindow::DrawPoint(QPainter& painter,int radius)
    45. {
    46. //组装点的路径图
    47. QPainterPath pointPath;
    48. pointPath.moveTo(-2,-2);
    49. pointPath.lineTo(2,-2);
    50. pointPath.lineTo(2,2);
    51. pointPath.lineTo(0,4);
    52. pointPath.lineTo(-2,2);
    53. //绘制13个小点
    54. for(int i=0;i<13;++i){
    55. QPointF point(0,0);
    56. painter.save();
    57. painter.setBrush(QColor(250,252,78));
    58. //计算并移动绘图对象中心点
    59. point.setX(radius*qCos(((210-i*20)*M_PI)/180));
    60. point.setY(radius*qSin(((210-i*20)*M_PI)/180));
    61. //计算并移动绘图对象的中心点
    62. painter.translate(point.x(),-point.y());
    63. //计算并选择绘图对象坐标
    64. painter.rotate(-120+i*20);
    65. //绘制路径
    66. painter.drawPath(pointPath);
    67. painter.restore();
    68. }
    69. }
    70. //刻度数字
    71. void MainWindow::DrawDigital(QPainter& painter,int radius)
    72. {
    73. //设置画笔,画笔默认NOPEN
    74. painter.setPen(QColor(255,255,255));
    75. QFont font;
    76. font.setFamily("Arial");
    77. font.setPointSize(15);
    78. font.setBold(true);
    79. painter.setFont(font);
    80. for(int i=0;i<13;++i){
    81. QPointF point(0,0);
    82. painter.save();
    83. point.setX(radius*qCos(((210-i*20)*M_PI)/180));
    84. point.setY(radius*qSin(((210-i*20)*M_PI)/180));
    85. painter.translate(point.x(),-point.y());
    86. painter.rotate(-120+i*20);
    87. painter.drawText(-25, 0, 50, 20,Qt::AlignCenter,QString::number(i*20));
    88. painter.restore();
    89. }
    90. //还原画笔
    91. painter.setPen(Qt::NoPen);
    92. }
    93. //扇形大圆
    94. void MainWindow::DrawCircle_bom(QPainter& painter,int radius)
    95. {
    96. //保存绘图对象
    97. painter.save();
    98. //计算大小圆路径
    99. QPainterPath outRing;
    100. outRing.moveTo(0,0);
    101. outRing.arcTo(-radius,-radius, 2*radius,2*radius,-30,240);
    102. outRing.closeSubpath();
    103. //设置画刷
    104. painter.setBrush(QColor(14,15,33));
    105. painter.drawPath(outRing);
    106. painter.restore();
    107. }
    108. //渐变发光内圈
    109. void MainWindow::DrawCircle_bom_shine(QPainter& painter,int radius)
    110. {
    111. painter.save();
    112. QRadialGradient radialGradient(0,0,radius,0,0);
    113. // radialGradient.setColorAt(0.5,QColor(8,77,197));
    114. radialGradient.setColorAt(0.5,QColor(10,68,185,150));
    115. radialGradient.setColorAt(1.0,Qt::transparent);
    116. painter.setBrush(QBrush(radialGradient));
    117. painter.drawRect(-radius,-radius,2*(radius),2*(radius));
    118. painter.restore();
    119. }
    120. //中间大圆
    121. void MainWindow::DrawCircle_bom_big(QPainter& painter,int radius)
    122. {
    123. //保存绘图对象
    124. painter.save();
    125. //计算大小圆路径
    126. QPainterPath inRing;
    127. inRing.moveTo(0,0);
    128. inRing.addEllipse(-radius+50,-radius + 50,2*(radius-50),2*(radius-50));
    129. //设置画刷
    130. painter.setBrush(QColor(10,20,30));
    131. painter.drawPath(inRing);
    132. painter.restore();
    133. }
    134. void MainWindow::DrawCircle_bom_small(QPainter& painter,int radius)
    135. {
    136. //保存绘图对象
    137. painter.save();
    138. //计算大小圆路径
    139. QPainterPath inRing;
    140. inRing.moveTo(0,0);
    141. inRing.addEllipse(-radius+50,-radius + 50,2*(radius-50),2*(radius-50));
    142. //设置画刷
    143. painter.setBrush(QColor(10,20,30));
    144. painter.drawPath(inRing);
    145. painter.restore();
    146. }
    147. void MainWindow::DrawCircle_arc(QPainter& painter,int radius)
    148. {
    149. QRect rect(-radius,-radius,2*radius,2*radius);
    150. QConicalGradient Conical(0,0,-70);
    151. Conical.setColorAt(0.1,QColor(255,88,127,200));//红色
    152. Conical.setColorAt(0.5,QColor(53,179,251,150));//蓝色
    153. painter.setBrush(Conical);
    154. painter.drawPie(rect,210*16,-(degRotate)*16);
    155. }
    156. //渐变发光外扇形
    157. void MainWindow::DrawCircle(QPainter& painter,int radius)
    158. {
    159. //保存绘图对象
    160. painter.save();
    161. //计算大小圆路径
    162. QPainterPath outRing;
    163. QPainterPath inRing;
    164. outRing.moveTo(0,0);
    165. inRing.moveTo(0,0);
    166. outRing.arcTo(-radius,-radius, 2*radius,2*radius,-30,240);
    167. inRing.addEllipse(-radius+50,-radius + 50,2*(radius-50),2*(radius-50));
    168. outRing.closeSubpath();
    169. //设置渐变色k
    170. QRadialGradient radialGradient(0,0,radius,0,0);
    171. radialGradient.setColorAt(1,QColor(0,82,199));
    172. radialGradient.setColorAt(0.92,Qt::transparent);
    173. //设置画刷
    174. painter.setBrush(radialGradient);
    175. //大圆减小圆
    176. painter.drawPath(outRing.subtracted(inRing));
    177. painter.restore();
    178. }
    179. //最外细圆线
    180. void MainWindow::DrawCircle_line(QPainter& painter,int radius)
    181. {
    182. //保存绘图对象
    183. painter.save();
    184. //计算大小圆路径
    185. QPainterPath outRing;
    186. QPainterPath inRing;
    187. outRing.moveTo(0,0);
    188. inRing.moveTo(0,0);
    189. outRing.arcTo(-radius,-radius, 2*radius,2*radius,-30,240);
    190. inRing.addEllipse(-radius+2,-radius+2,2*(radius-2),2*(radius-2));
    191. outRing.closeSubpath();
    192. //设置画刷
    193. painter.setBrush(QColor(5,228,255));
    194. //大圆减小圆
    195. painter.drawPath(outRing.subtracted(inRing));
    196. painter.restore();
    197. }
    198. //绘制刻度
    199. void MainWindow::DrawSmallScale(QPainter& painter,int radius)
    200. {
    201. //组装点的路径图
    202. QPainterPath pointPath_small;
    203. pointPath_small.moveTo(-2,-2);
    204. pointPath_small.lineTo(2,-2);
    205. pointPath_small.lineTo(2,8);
    206. pointPath_small.lineTo(-2,8);
    207. QPainterPath pointPath_big;
    208. pointPath_big.moveTo(-2,-2);
    209. pointPath_big.lineTo(2,-2);
    210. pointPath_big.lineTo(2,20);
    211. pointPath_big.lineTo(-2,20);
    212. //绘制121个小点
    213. for(int i=0;i<121;i+=2){
    214. QPointF point(0,0);
    215. painter.save();
    216. point.setX(radius*qCos(((210-i*2)*M_PI)/180));
    217. point.setY(radius*qSin(((210-i*2)*M_PI)/180));
    218. painter.translate(point.x(),-point.y());
    219. painter.rotate(-120+i*2);
    220. if(i<80)
    221. {
    222. painter.setBrush(QColor(255,255,255));
    223. }
    224. if(i>=80)
    225. {
    226. painter.setBrush(QColor(235,70,70));
    227. }
    228. if(i%5 == 0)
    229. {
    230. painter.drawPath(pointPath_big);//绘画大刻度
    231. }else
    232. {
    233. painter.drawPath(pointPath_small);//绘画小刻度
    234. }
    235. painter.restore();
    236. }
    237. }
    238. //绘制文字
    239. void MainWindow::DrawUnit(QPainter& painter,int radius)
    240. {
    241. painter.save();
    242. painter.setPen(QColor(255,255,255));
    243. QFont font;
    244. font.setFamily("Arial");
    245. font.setPointSize(16);
    246. font.setBold(true);
    247. painter.setFont(font);
    248. painter.drawText(-50, -radius, 100, 20,Qt::AlignCenter,QString("km/h"));
    249. painter.drawText(-60, -radius + 130, 120, 40,Qt::AlignCenter,QString("当前车速"));
    250. painter.setPen(QColor(255,255,255,50));
    251. painter.drawText(-120, -radius + 280, 250, 40,Qt::AlignCenter,QString("-请按space键加速-"));
    252. painter.restore();
    253. }
    254. //绘制实时时速数字
    255. void MainWindow::DrawNum(QPainter& painter,int radius)
    256. {
    257. painter.save();
    258. painter.setPen(QColor(255,255,255));
    259. QFont font;
    260. font.setFamily("Arial");
    261. font.setPointSize(45);
    262. painter.setFont(font);
    263. painter.drawText(-75, -radius - 20, 150, 100,Qt::AlignCenter,QString::number(degRotate));
    264. painter.restore();
    265. }
    266. //绘制指针
    267. void MainWindow::DrawPointer(QPainter& painter,int radius)
    268. {
    269. //组装点的路径图
    270. QPainterPath pointPath;
    271. pointPath.moveTo(10,0);
    272. pointPath.lineTo(1,-radius);
    273. pointPath.lineTo(-1,-radius);
    274. pointPath.lineTo(-10,0);
    275. pointPath.arcTo(-10,0,20,20,180,180);
    276. QPainterPath inRing;
    277. inRing.addEllipse(-5,-5,10,10);
    278. painter.save();
    279. //计算并选择绘图对象坐标
    280. painter.rotate(degRotate - 120);
    281. painter.setBrush(QColor(255,255,255));
    282. painter.drawPath(pointPath.subtracted(inRing));
    283. painter.restore();
    284. }
    285. //动态增加时速画面效果
    286. void MainWindow::slot_speed_changed()
    287. {
    288. if(direction == 1)//加速
    289. {
    290. degRotate++;
    291. if(degRotate > 240)
    292. degRotate = 240;
    293. }
    294. else if(direction == 0)//减速
    295. {
    296. degRotate--;
    297. if(degRotate < 0)
    298. {
    299. degRotate = 0;
    300. myTimer->stop();
    301. }
    302. }
    303. update();//刷新画面。很重要!
    304. }
    305. //按键按下事件
    306. void MainWindow::keyPressEvent(QKeyEvent *event)
    307. {
    308. if(event->key() == Qt::Key_Space)
    309. {
    310. if(direction == 0)
    311. {
    312. myTimer->start(1);
    313. direction = 1;
    314. }
    315. }
    316. }
    317. //按键释放事件
    318. void MainWindow::keyReleaseEvent(QKeyEvent *event)
    319. {
    320. if(event->key() == Qt::Key_Space)
    321. {
    322. direction = 0;
    323. }
    324. }
    325. MainWindow::~MainWindow()
    326. {
    327. delete ui;
    328. }

    main.cpp

    1. #include "mainwindow.h"
    2. #include
    3. int main(int argc, char *argv[])
    4. {
    5. QApplication a(argc, argv);
    6. MainWindow w;
    7. w.show();
    8. return a.exec();
    9. }

  • 相关阅读:
    面试题:说说Java并发运行中的一些安全问题
    MacOS下brew切换为国内源
    [软考中级]软件设计师-计算机网络
    Redis-带你深入学习数据类型Hash【面试重点】
    ATFX汇市:10月美国名义CPI年率大降,美元指数创近三月新低
    关于ETL的两种架构(ETL架构和ELT架构)
    音视频 - 视频编码原理
    【Java编程进阶之路--三大特性】
    共谋工业3D视觉发展,深眸科技以自研解决方案拓宽场景应用边界
    深度探索.NET Feature Management功能开关的魔法
  • 原文地址:https://blog.csdn.net/tankeven/article/details/136384375