参考链接:https://www.jb51.net/article/279998.htm
在此基础上做了优化。
效果图:
鼠标左键点击显示当前点相对于圆心的距离和方位
// 头文件
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QPainter>
#include <QTime>
#include <QTimer>
#include <QDebug>
#include <QPoint>
#include <QtMath>
#include <QMouseEvent>
#include <QLabel>
#include <QToolTip>
#include <cmath>
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
public slots:
void timerTimeOut();
private slots:
void mousePressEvent(QMouseEvent *event);
protected:
void paintEvent(QPaintEvent *event) override;
private:
//----------------------------------------------------
// 函数名称:drawAzimuth
// 作用:绘制雷达扫描图方位
// 参数:参数一:QPainter对象,类型:QPainter
// 参数二、三:在指定坐标(x, y)上绘制方位文本,类型:int
// 参数四:绘制的方位数据,类型:int
//-----------------------------------------------------
void drawAzimuth(QPainter *painter, int x, int y, int azimuth);
//----------------------------------------------------
// 函数名称:drawRange
// 作用:绘制雷达扫描图量程
// 参数:参数一:QPainter对象,类型:QPainter
// 参数二、三:在指定坐标(x, y)上绘制方位文本,类型:int
// 参数四:绘制的量程数据,类型:int
//-----------------------------------------------------
void drawRange(QPainter *painter, int x, int y, int range);
private:
// 圆心坐标
int CoorX;
int CoorY;
// 直径
int diameter;
// 圈数
int NumTurns;
};
#endif // WIDGET_H
// cpp文件
#include "widget.h"
#include <QLabel>
#include <QVBoxLayout>
QTimer *timer = new QTimer();
int m_angle=0;
int alpha=0;
double cir_size=5;
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
setPalette(Qt::black); setAutoFillBackground(true);//强制设置背景颜色为黑色
connect(timer,SIGNAL(timeout()),this,SLOT(timerTimeOut()));//用槽函数控制雷达扫描效果。
// setFixedSize(600,600);
timer->start(10);
}
Widget::~Widget()
{
}
void Widget::timerTimeOut()
{
timer->start(10);
if(m_angle < -360){
m_angle=0;
}//实现无缝连接,且保证m_angle的值不会溢出
if(alpha >= 255){
alpha = 0;
}
if(cir_size > 10){
cir_size=5;
}
update();
}
void Widget::paintEvent(QPaintEvent *event)//此函数自动执行,实现扫描动画效果
{
Q_UNUSED(event);
QPainter painter(this);
QPen pen;
painter.setRenderHint(QPainter::Antialiasing);
painter.setPen(QPen(qRgba(128, 255, 0,250)));
//网格改成坐标系
int x = 280;//原本为240,右移40,下移60
int y = 300;
CoorX = this->width() / 2;
CoorY = this->height() / 2;
int range = 50;
diameter = 250;
NumTurns = 5;
/** 直径按照480处理 每隔48px画一个圆 绘制雷达图**/
// 从外到内画圆
QPoint center(CoorX,CoorY);
for(int i = 0;i < NumTurns;i++)
{
painter.drawEllipse(center, diameter - range * i, diameter - range * i);
}
drawRange(&painter, CoorX, CoorY, range);
/** 画外圈刻度值,将坐标系移动到圆心 **/
painter.translate(CoorX, CoorY);
painter.setPen(QPen(qRgba(255, 255, 0,250)));
painter.setFont(QFont("Calibri",10));
for(int i=1;i<=360;i++){
painter.rotate(1);
painter.drawLine(0, diameter * -1, 0, diameter * -1 + 5);
}
for(int i=1;i<=72;i++){
painter.rotate(5);
painter.drawLine(0, diameter * -1, 0, diameter * -1 + 8);
}
for(int i=1;i<=36;i++){
painter.setRenderHint(QPainter::Antialiasing);
painter.rotate(10);
painter.drawLine(0, diameter * -1,0, diameter * -1 + 12);
}
for(int i = 1;i <= 4;i++){
// 外圈刻度值
painter.drawLine(0, 0, 0, diameter * -1);
// 绘制方位
drawAzimuth(&painter, -10, -260, (i - 1) * 90);
// 顺时针旋转90度
painter.rotate(90);
}
painter.translate(-x,-y);//恢复坐标系
/** 绘制扫描效果 **/
QConicalGradient gradient(x, y, m_angle + 360);
gradient.setColorAt(0.1, QColor(128, 255, 0, 150));
gradient.setColorAt(0.7, QColor(0, 255, 0, 0));//尾部
painter.setBrush(gradient);
painter.setPen(QPen(Qt::NoPen));//去掉外框线
if (width() > height())
{
painter.drawPie(40, 60, 480, 480, m_angle * 16, 360 * 16);
}
else
{
painter.drawPie(40, 60, 480, 480, m_angle * 16, 360 * 16);
}
m_angle -= 1;//每次旋转1度
alpha += 2;
cir_size += 0.1;
//模拟画出可疑点
painter.setBrush(QBrush(QColor(50, 255, 200, alpha)));
painter.drawEllipse(60+120,60+161, cir_size, cir_size);
painter.drawEllipse(60+240,60+161, cir_size, cir_size);
painter.drawEllipse(60+300,60+300,cir_size,cir_size);
painter.setBrush(QBrush(QColor(50, 255, 200,(alpha+50)%255)));
painter.drawEllipse(60+160,60+121,cir_size,cir_size);
painter.drawEllipse(60+60,60+191,cir_size,cir_size);
painter.drawEllipse(60+260,60+221,cir_size,cir_size);
painter.setBrush(QBrush(QColor(50, 255, 200,(alpha+100)%255)));
painter.drawEllipse(60+210,60+181,cir_size,cir_size);
painter.drawEllipse(60+10,60+281,cir_size,cir_size);
painter.drawEllipse(60+100,60+81,cir_size,cir_size);
// 画出批号
QFont font = QFont("Arial",11);
painter.setFont(font);
painter.setPen(QPen(Qt::red));
painter.drawText(60+120-4,60+161-4, "p");
painter.drawText(60+240-4,60+161-4, "p");
painter.drawText(60+300-4,60+300-4, "p");
painter.drawText(60+160-4,60+121-4, "p");
painter.drawText(60+60-4,60+191-4, "p");
painter.drawText(60+260-4,60+221-4, "p");
painter.drawText(60+210-4,60+181-4, "p");
painter.drawText(60+10-4,60+281-4, "p");
painter.drawText(60+100-4,60+81-4, "p");
}
void Widget::drawAzimuth(QPainter *painter, int x, int y, int azimuth)
{
if(azimuth == 180)
{
painter->rotate(180);
QFont font = QFont("Arial",16);
QString str = QString::number(azimuth);
painter->setFont(font);
painter->drawText(x - 15, y + 530, str);
painter->rotate(180);
}
else
{
QFont font = QFont("Arial",16);
QString str = QString::number(azimuth);
painter->setFont(font);
painter->drawText(x, y, str);
}
}
void Widget::drawRange(QPainter* painter, int x, int y, int range)
{
for(int i = 1;i <= 5;i++)
{
painter->drawText(x, y + range * i - 3, QString::number(range * i));
painter->drawText(x, y - range * i + 13, QString::number(range * i));
painter->drawText(x + range * i - 20, y, QString::number(range * i));
painter->drawText(x - range * i, y, QString::number(range * i));
}
}
void Widget::mousePressEvent(QMouseEvent *event)
{
//如果鼠标左键按下
if (event->type() == QEvent::MouseButtonPress) {
//获取鼠标在事件接收者中的位置pos
// qDebug() << event->pos();
// qDebug() << event->pos().x();
// qDebug() << event->pos().y();
//if(event->x() )
int x = event->x();
int y = event->y();
// 计算距离
// 圆心坐标(280, 300)
int distance = sqrt(pow(x - CoorX, 2) + pow(y - CoorY, 2));
// 计算方位
double azimuth = atan2(y - CoorY, x - CoorX) * 180 / M_PI;
QPoint point = this->mapToGlobal(event->pos()); //坐标转换
point.setX(point.x() - 20);
point.setY(point.y() - 50);
if(static_cast<int>(azimuth) < -90 && static_cast<int>(azimuth) > -180)
{
QToolTip::showText(point, QString("距离: %1\n方位: %2").arg(distance).arg(azimuth + 450));
}
else
{
QToolTip::showText(point, QString("距离: %1\n方位: %2").arg(distance).arg(azimuth + 90));
}
}
}
main.cpp不作修改
目前完成了这些效果,数据写死了,后续还得封装接口。
知识点记录:
QToolTip函数,用于显示提示信息,案例中鼠标点击的提示信息就是由该函数完成,该函数还可实现鼠标点击、悬停在控件上显示提示信息。
参考链接
https://blog.csdn.net/chenyijun/article/details/49803767