当前位置:   article > 正文

Qt总结之六:QPaintEvent绘制雷达图_qwt 绘制雷达图

qwt 绘制雷达图

前言

关于雷达样式可参考文章:https://blog.csdn.net/Aidam_Bo/article/details/84260883


一、代码

头文件.h

  1. #ifndef RADARSCAN_H
  2. #define RADARSCAN_H
  3. #include <QtWidgets/QWidget>
  4. #include "ui_radarscan.h"
  5. class RadarScan : public QWidget
  6. {
  7. Q_OBJECT
  8. public:
  9. RadarScan(QWidget *parent = 0);
  10. ~RadarScan();
  11. QPixmap paintWidget();
  12. protected:
  13. void paintEvent(QPaintEvent *event);
  14. void resizeEvent(QResizeEvent *event);
  15. protected slots:
  16. void timerTimeOut();
  17. private:
  18. QTimer *timer;
  19. QPoint point;
  20. int i_diameter = 0;
  21. double d_angle = 0;
  22. QList<QPixmap> list_pixmap;
  23. private:
  24. Ui::RadarScanClass ui;
  25. };
  26. #endif // RADARSCAN_H

实现.cpp

  1. #include "radarscan.h"
  2. #include <QPainter>
  3. #include <QPen>
  4. #include <QDebug>
  5. #include <QLinearGradient>
  6. #include <QTimer>
  7. #include <QTime>
  8. RadarScan::RadarScan(QWidget *parent)
  9. : QWidget(parent)
  10. {
  11. ui.setupUi(this);
  12. this->setStyleSheet("background-color:black");//设置窗口背景色为黑色
  13. timer = new QTimer();
  14. connect(timer, SIGNAL(timeout()), this, SLOT(timerTimeOut()));
  15. timer->start(10);
  16. }
  17. RadarScan::~RadarScan()
  18. {
  19. }
  20. void RadarScan::resizeEvent(QResizeEvent *event)
  21. {
  22. if (this->width() > this->height()){
  23. point = QPoint((this->width() - this->height()) / 2 + (this->height() - 12) / 2, this->height() / 2);
  24. i_diameter = this->height() - 12;
  25. }
  26. else{
  27. point = QPoint(this->width() / 2, (this->height() - this->width()) / 2 + (this->width() - 12) / 2);
  28. i_diameter = this->width() - 12;
  29. }
  30. }
  31. void RadarScan::timerTimeOut()
  32. {
  33. timer->start(10);
  34. d_angle += 3.14 / 720;
  35. if (d_angle >= 6.28){
  36. d_angle = 0;
  37. }
  38. update();
  39. }
  40. void RadarScan::paintEvent(QPaintEvent *event)
  41. {
  42. QPainter p_painter(this);
  43. //反锯齿
  44. p_painter.setRenderHint(QPainter::Antialiasing);
  45. p_painter.drawPixmap(0, 0, this->width(), this->height(), paintWidget());
  46. QWidget::paintEvent(event);
  47. }
  48. QPixmap RadarScan::paintWidget()
  49. {
  50. QPixmap pixmap(this->width(), this->height());
  51. QPainter p_painter(&pixmap);
  52. QPen pen;
  53. QTime timedebug;
  54. timedebug.start();
  55. //反锯齿
  56. p_painter.setRenderHint(QPainter::Antialiasing);
  57. pixmap.fill(Qt::black);
  58. pen.setColor(Qt::green);
  59. p_painter.setPen(pen);
  60. pen.setColor(Qt::gray);
  61. p_painter.setPen(pen);
  62. p_painter.drawLine(point.x(), point.y() - i_diameter / 2 - 10, point.x(), point.y() + i_diameter / 2 + 10);//画坐标
  63. p_painter.drawLine(point.x() - i_diameter / 2 - 10, point.y(), point.x() + i_diameter / 2 + 10, point.y());
  64. pen.setColor(Qt::green);
  65. p_painter.setPen(pen);
  66. for (int i = 0; i<6; i++){
  67. p_painter.drawEllipse(point.x() - i_diameter*0.2*i / 2, point.y() - i_diameter*0.2*i / 2, i_diameter*0.2*i, i_diameter*0.2*i);
  68. }
  69. QConicalGradient conical_gradient(point, (6.28 - d_angle) / 6.28 * 720);//定义圆心和渐变的角度
  70. conical_gradient.setColorAt(0, Qt::green);
  71. conical_gradient.setColorAt(0.2, QColor(255, 255, 255, 0));
  72. p_painter.setBrush(conical_gradient);
  73. p_painter.drawEllipse(point.x() - i_diameter / 2, point.y() - i_diameter / 2, i_diameter, i_diameter);
  74. qDebug() << "time_end=" << timedebug.elapsed() << "ms";
  75. return pixmap;
  76. }

二、细节实现


(1)重写resizeEvent函数,当窗口缩放时,对绘图的大小也进行缩放:

  1. void RadarScan::resizeEvent(QResizeEvent *event)
  2. {
  3.     if(this->width() > this->height()){
  4.         point = QPoint((this->width()-this->height())/2+(this->height()-12)/2,this->height()/2);
  5.         i_diameter = this->height()-12;
  6.     }else{
  7.         point = QPoint(this->width()/2,(this->height()-this->width())/2+(this->width()-12)/2);
  8.         i_diameter = this->width()-12;
  9.     }
  10. }


(2)在绘图函数中主要使用了QPixmap的定义画布,QPEN定义画笔,QConicalGradient对图形进行渐变填充,drawEllipse进行画圆:

  1. QPixmap Widget::paintWidget()
  2. {
  3.     QPixmap pixmap(this->width(),this->height());
  4.     QPainter p_painter(&pixmap);
  5.     QPen pen;
  6.     QTime timedebug;
  7.     timedebug.start();
  8.     //反锯齿
  9.     p_painter.setRenderHint(QPainter::Antialiasing);
  10.     pixmap.fill(Qt::black);
  11.  
  12.     pen.setColor(Qt::green);
  13.     p_painter.setPen(pen);
  14.  
  15.     pen.setColor(Qt::gray);
  16.     p_painter.setPen(pen);
  17.     p_painter.drawLine(point.x(),point.y()-i_diameter/2-10,point.x(),point.y()+i_diameter/2+10);//画坐标
  18.     p_painter.drawLine(point.x()-i_diameter/2-10,point.y(),point.x()+i_diameter/2+10,point.y());
  19.     pen.setColor(Qt::green);
  20.     p_painter.setPen(pen);
  21.     for(int i=0; i<6; i++){
  22.         p_painter.drawEllipse(point.x()-i_diameter*0.2*i/2,point.y()-i_diameter*0.2*i/2,i_diameter*0.2*i,i_diameter*0.2*i);
  23.     }
  24.  
  25.     QConicalGradient conical_gradient(point,(6.28-d_angle)/6.28*720);//定义圆心和渐变的角度
  26.     conical_gradient.setColorAt(0,Qt::green);
  27.     conical_gradient.setColorAt(0.2,QColor(255,255,255,0));
  28.     p_painter.setBrush(conical_gradient);
  29.     p_painter.drawEllipse(point.x()-i_diameter/2,point.y()-i_diameter/2,i_diameter,i_diameter);
  30.  
  31.  
  32.     qDebug()<<"time_end="<<timedebug.elapsed()<<"ms";
  33.  
  34.     return pixmap;
  35.  
  36. }


(3)QTimer定义定时器连接槽函数,当定时溢出时对图像进行刷新,同时重新开启定时,定时单位是毫秒:

  1. void Widget::timerTimeOut()
  2. {
  3.     timer->start(10);
  4.     d_angle += 3.14/720;
  5.     if(d_angle >= 6.28){
  6.         d_angle = 0;
  7.     }
  8.     update();
  9.  
  10. }


(4)最后对paintEven进行重构:

  1. void Widget::paintEvent(QPaintEvent *event)
  2. {
  3.     QPainter p_painter(this);
  4.     //反锯齿
  5.     p_painter.setRenderHint(QPainter::Antialiasing);
  6.  
  7.     p_painter.drawPixmap(0,0,this->width(),this->height(),paintWidget());
  8.  
  9.     QWidget::paintEvent(event);
  10. }

三、效果展示


(1)得到的一直在扫描的图像:


(2)打印记录时间:

 


总结

源码:

代码资源下载:https://download.csdn.net/download/aidam_bo/10878728(paintEven绘图)

 

改善:

因为图像会随着窗口的拉伸而变大,当图像变得比较大时,绘图的时间就会变的比较长,图像越大绘图时间越长,看着图像的移动比较缓慢。目前暂时想到了几种简单的思路:

1,使用图片:paintEvent只绘制坐标,扫描的动画使用图片的格式来实现,对图片不断进行旋转,这种方法对图片的透明度有要求。

2,使用多线程:使用多线程同时绘制多个图形,使用信号量对图形进行读取显示。

3,改变渐变填充的区域:这里的渐变填充是填充了整个圆形区域,可以改变填充的区域,使用drawPie绘制扇形进行渐变填充。

4,使用Qt封装的openGL或者第三方库,例如:https://sourceforge.net/projects/qfi/ 这种(这是飞行仪表的开源库,代码很短)。
 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小丑西瓜9/article/detail/170654
推荐阅读
相关标签
  

闽ICP备14008679号