Qt总结之七:QPaintEvent绘制雷达图(二)
前言
这里使用另一套框架写的雷达扫描图
这里PaintEvent事件比上一个版本写的好,但是不喜欢Widget嵌套的方式,后续会把两个版本整合到一起。
一、实现原理
雷达效果包括三个部分:背景、转动的扇形和闪烁的点。
(1)背景的实现很简单,首先填充背景色,然后绘制横纵坐标轴以及三个同心圆。代码如下:
//背景painter.fillRect(rect(),QColor(15,45,188));//边长int len = m_drawArea.width();//底盘(x轴、y轴和3个圆)painter.setPen(QPen(Qt::white));painter.drawLine(m_drawArea.topLeft() + QPoint(0,len/2),m_drawArea.topRight() + QPoint(0,len/2));painter.drawLine(m_drawArea.topLeft() + QPoint(len/2,0),m_drawArea.bottomLeft() + QPoint(len/2,0));painter.drawEllipse(m_drawArea.center(),len/2,len/2);painter.drawEllipse(m_drawArea.center(),len/3,len/3);painter.drawEllipse(m_drawArea.center(),len/6,len/6);
在这里有个m_drawArea是用来描述绘制雷达的区域的。先确定这个绘制区域,更容易计算绘制的内容。 m_drawArea的大小在resizeEvent事件中确定。
void CRadar::resizeEvent(QResizeEvent *event)
{//以较短的边长作为绘制区域边长if(width() > height()){m_drawArea = QRect((width() - height())/2,0,height(),height());}else{m_drawArea = QRect(0,(height() - width())/2,width(),width());}m_drawArea.adjust(10,10,-10,-10);
}
为了确保雷达为圆形,我们以较短的边作为矩形的边长。然后使用adjust缩小一点。adjust前两个参数为左上角x和y的增量,后两个参数为右下角x和y的增量。
(2)转动部分由一个扇形和一条直线组成。扇形使用了锥形渐变色。代码如下:
//转动部分//---//线qreal x = m_drawArea.center().x() + (qreal)len/2 * cos(-m_pieRotate*3.14159/180);qreal y = m_drawArea.center().y() + (qreal)len/2 * sin(-m_pieRotate*3.14159/180);painter.setPen(QPen(Qt::white));painter.drawLine(m_drawArea.center(),QPointF(x,y));//----//扇形QConicalGradient gradient;gradient.setCenter(m_drawArea.center());gradient.setAngle(m_pieRotate + 180); //渐变与旋转方向恰好相反,以扇形相反的边作为渐变角度。gradient.setColorAt(0.4,QColor(255,255,255,100)); //从渐变角度开始0.5 - 0.75为扇形区域,由于Int类型计算不精确,将范围扩大到0.4-0.8gradient.setColorAt(0.8,QColor(255,255,255,0));painter.setBrush(QBrush(gradient));painter.setPen(Qt::NoPen);painter.drawPie(m_drawArea,m_pieRotate*16,90*16);
直线的绘制很简单,只需要计算转动角度对应圆上的点的坐标即可。扇形的绘制也很简单。难点在于渐变色的应用,由于锥形渐变是逆时针的,而我们的雷达是顺时针的转动。所以要计算好扇形区域在渐变的哪个范围。这里设置了渐变角度为扇形角度旋转180度,那么扇形区域应该在渐变角度的0.5 - 0.75范围内。由于这里使用的是int类型,怕计算的不精确,将渐变颜色的范围设置大一些。
(3)第三部分是随机闪烁的点,用来点缀。在这里使用了一个list存放点的坐标,另一个list存放这些点的颜色alapha值。使用一个定时器随机改变这些点的坐标值和alapha值。
void CRadar::timerEvent(QTimerEvent *event)
{if(m_timerId == event->timerId()){m_pieRotate -= 10;update();}else if(m_pointTimerId == event->timerId()){//随机更换装饰的点for(int i = 0; i < m_points.count(); ++i){int offsetX = rand()%m_drawArea.width();int offsetY = rand()%m_drawArea.width();int alapha = rand()%255;m_points.replace(i,QPoint(offsetX,offsetY) + m_drawArea.topLeft());m_pointsAlapha.replace(i,alapha);}update();}
}
第一个定时器是用来改变转动部分的角度的。第二个定时器才是用来改变闪烁点的。
二、代码区
radar.h
#ifndef RADAR_H
#define RADAR_H#include <QWidget>class Radar : public QWidget
{Q_OBJECTpublic:Radar(QWidget *parent);~Radar();
protected:void paintEvent(QPaintEvent *event); //绘制事件void resizeEvent(QResizeEvent *event); //大小重置事件void timerEvent(QTimerEvent *event); //定时器事件
private:QRect m_drawArea; //绘制区域int m_pieRotate; //扇形旋转区域int m_timerId; //定时器IDint m_pointTimerId; //变更点定时器int m_nSpeed; //速度QList<QPoint> m_points; //绘制点QList<int> m_pointsAlapha; //绘制点颜色alapha值};#endif // RADAR_H
radarscannice.h
#ifndef RADARSCANNICE_H
#define RADARSCANNICE_H#include <QtWidgets/QWidget>
#include "ui_radarscannice.h"class RadarScanNice : public QWidget
{Q_OBJECTpublic:RadarScanNice(QWidget *parent = 0);~RadarScanNice();private:Ui::RadarScanNiceClass ui;
};#endif // RADARSCANNICE_H
radar.cpp
#include "radar.h"
#include <QPainter>
#include <QTimerEvent>
#include <QConicalGradient>
#include <qDebug>Radar::Radar(QWidget *parent): QWidget(parent)
{//初始化m_pieRotate = 0;m_timerId = -1;m_nSpeed = 50;m_points << QPoint() << QPoint() << QPoint() << QPoint() << QPoint();m_pointsAlapha << 100 << 100 << 100 << 100 << 100;//启动定时器m_timerId = startTimer(m_nSpeed);m_pointTimerId = startTimer(1200);
}Radar::~Radar()
{}
void Radar::paintEvent(QPaintEvent *event)
{QPainter painter(this);//抗锯齿painter.setRenderHint(QPainter::Antialiasing);//背景painter.fillRect(rect(), QColor(15, 45, 188));//边长int len = m_drawArea.width();//底盘(x轴、y轴和3个圆)painter.setPen(QPen(Qt::white));painter.drawLine(m_drawArea.topLeft() + QPoint(0, len / 2), m_drawArea.topRight() + QPoint(0, len / 2));painter.drawLine(m_drawArea.topLeft() + QPoint(len / 2, 0), m_drawArea.bottomLeft() + QPoint(len / 2, 0));painter.drawEllipse(m_drawArea.center(), len / 2, len / 2);painter.drawEllipse(m_drawArea.center(), len / 3, len / 3);painter.drawEllipse(m_drawArea.center(), len / 6, len / 6);//转动部分//---//线qreal x = m_drawArea.center().x() + (qreal)len / 2 * cos(-m_pieRotate*3.14159 / 180);qreal y = m_drawArea.center().y() + (qreal)len / 2 * sin(-m_pieRotate*3.14159 / 180);painter.setPen(QPen(Qt::white));painter.drawLine(m_drawArea.center(), QPointF(x, y));//----//扇形QConicalGradient gradient;gradient.setCenter(m_drawArea.center());gradient.setAngle(m_pieRotate + 180); //渐变与旋转方向恰好相反,以扇形相反的边作为渐变角度。gradient.setColorAt(0.4, QColor(255, 255, 255, 100)); //从渐变角度开始0.5 - 0.75为扇形区域,由于Int类型计算不精确,将范围扩大到0.4-0.8gradient.setColorAt(0.8, QColor(255, 255, 255, 0));painter.setBrush(QBrush(gradient));painter.setPen(Qt::NoPen);painter.drawPie(m_drawArea, m_pieRotate * 16, 90 * 16);//装饰-随机点for (int i = 0; i < m_points.count(); ++i){int colorAlaph = m_pointsAlapha.at(i);painter.setPen(QPen(QColor(255, 255, 255, colorAlaph), 3));painter.drawPoint(m_points.at(i));}
}void Radar::resizeEvent(QResizeEvent *event)
{//以较短的边长作为绘制区域边长if (width() > height()){m_drawArea = QRect((width() - height()) / 2, 0, height(), height());}else{m_drawArea = QRect(0, (height() - width()) / 2, width(), width());}m_drawArea.adjust(10, 10, -10, -10);
}void Radar::timerEvent(QTimerEvent *event)
{if (m_timerId == event->timerId()){m_pieRotate -= 10;update();}else if (m_pointTimerId == event->timerId()){//随机更换装饰的点for (int i = 0; i < m_points.count(); ++i){int offsetX = rand() % m_drawArea.width();int offsetY = rand() % m_drawArea.width();int alapha = rand() % 255;m_points.replace(i, QPoint(offsetX, offsetY) + m_drawArea.topLeft());m_pointsAlapha.replace(i, alapha);}update();}
}
radarscannice.cpp
#include "radarscannice.h"
#include "radar.h"RadarScanNice::RadarScanNice(QWidget *parent): QWidget(parent)
{ui.setupUi(this);Radar* radar = new Radar(this);radar->setFixedSize(300, 300);radar->move(150, 50);
}RadarScanNice::~RadarScanNice()
{}
main.cpp
#include "radarscannice.h"
#include <QtWidgets/QApplication>int main(int argc, char *argv[])
{QApplication a(argc, argv);RadarScanNice w;w.show();return a.exec();
}
效果图:
Qt总结之七:QPaintEvent绘制雷达图(二)相关推荐
- Qt总结之六:QPaintEvent绘制雷达图
前言 关于雷达样式可参考文章:https://blog.csdn.net/Aidam_Bo/article/details/84260883 一.代码 头文件.h #ifndef RADARSCAN_ ...
- 三种方法绘制雷达图,用最快的时间做出最好看的可视化图表
雷达图是通过多个离散属性比较对象的最直观工具,掌握绘制雷达图的方法将会为生活和工作带来乐趣. 本例数据来源于网络,某大学本科一年级不同分院学生在五种核心通识能力方面的数据,使用多个工具来绘制多级雷达图 ...
- Python matplotlib绘制雷达图
Python matplotlib绘制雷达图 本篇文章介绍使用matplotlib绘制雷达图. 雷达图也被称为网络图,蜘蛛图,星图,蜘蛛网图,是一个不规则的多边形.雷达图可以形象地展示相同事物的多维指 ...
- 带着canvas去流浪系列之六 绘制雷达图
[摘要] 用canvas原生API实现百度Echarts基本图表. 示例代码托管在:http://www.github.com/dashnowords/blogs 一. 任务说明 使用原生canvas ...
- 【带着canvas去流浪(6)】绘制雷达图
目录 一. 任务说明 二. 重点提示 三. 示例代码 示例代码托管在:http://www.github.com/dashnowords/blogs 博客园地址:<大史住在大前端>原创博文 ...
- echarts 雷达图_【带着canvas去流浪】绘制雷达图
使用原生canvasAPI绘制雷达图.(截图以及数据来自于百度Echarts官方示例库[查看示例链接]). 二. 重点提示 雷达图绘制的看起来并不复杂,无非就是一些路径点的连线,其中的难点都在于一些细 ...
- MATLAB绘制雷达图并导出矢量图到Visio编辑(论文用图)
MATLAB绘制雷达图并导出矢量图到Visio编辑(论文用图) 前言: matlab绘制雷达图 雷达图(Radar Chart)又被叫做蜘蛛网图(Spider Chart),适用于显示三个或更多的 ...
- matplotlib绘制雷达图之基本配置——万能模板案例
目录 介绍 应用场景 案例一(成绩雷达图重叠) 案例二(成绩雷达图左右图) 极坐标 每文一语 介绍 雷达图是以从同一点开始的轴上表示的三个或更多个定量变量的二维图表的形式显示多变量数据的图形方法.轴的 ...
- tableau绘制雷达图(4步法)
为什么要用tableau? 我称之为(静态.动态图的区别) 我们可以用python,excel进行雷达图的绘制,那么为什么要用tableau? 因为,tableau的图可以是动态的多个视图的整合,你可 ...
最新文章
- (转)径向模糊效果shader
- hdu 1233 还是畅通工程 Kruskal 最小生成树 并查集
- 不一样的STAR法则
- 针对【H-2017年信息基础班(周一班)】某些同学恶意使用lyl洛谷的谴责
- ASP.NET Core 消息传递:MediatR
- 蚂蚁金服 3 个项目进入 CNCF 云原生全景图 | 开源
- 在Ubuntu 18.04系统上安装和配置DBeaver的步骤
- 云计算学习笔记003---Hadoop简介,hadoop实现原理,NoSQL介绍...与传统关系型数据库对应关系,云计算面临的挑战
- mysql主从同步问题_mysql主从同步问题整理
- 电信机顶盒,废弃机顶盒复活,华为电信定制机顶盒,固件。设置关闭限制apk选项。安装自己所需的apk软件。
- 软件测试ios打包,苹果测试iOS打包成 ipa包
- 2020第一本书《自私的基因》
- 一位华裔复活了美国奥数国家队:掌舵6年4次夺冠,打破中国队“垄断”
- flac格式怎么转换mp3格式?
- 力扣第235题“二叉搜索树的最近公共先祖”的解题思路
- burp如何设置微信小程序代理
- BERT-MRC:统一化MRC框架提升NER任务效果
- 数字滤波器matlab仿真_模拟IC笔记(1)——PLL MATLAB建模与行为仿真
- c++ tm结构体和time_t时间戳的转换
- 安装坑——rational rose
热门文章
- centos6.5 redis3 开机自动启动命令设置
- 一念心动,一生绵延——如何修复min pulse width?
- .NET程序集(Assembly)
- -xdebug java8_多种高级debug方法,帮你更快定位问题
- 计算机监控系统必须有直流系统吗,变电站直流屏是否必须用蓄电池
- java成员修饰词 友好的_Java的类成员访问权限修饰词(以及类访问权限)
- 远程调试Eclipse插件的设置
- oracle r修改表名,oracle中修改表名
- python na不显示 占位_Python学习之路—Python基础(一)
- 正版Fiddler下载地址