QT实现雷达扫描

参考链接:https://www.jb51.net/article/279998.htm

在此基础上做了优化。
效果图:
QT实现雷达扫描_第1张图片
鼠标左键点击显示当前点相对于圆心的距离和方位

// 头文件
#ifndef WIDGET_H
#define WIDGET_H

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

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 
#include 

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

你可能感兴趣的:(qt,开发语言)