QT实现雷达扫描

news2024/11/16 19:39:15

参考链接: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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/757288.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Java并发编程(11) —— CountDownLatch原理详解

一、CountDownLatch介绍 在日常开发中经常会遇到需要在主线程中开启多个线程去并行执行任务&#xff0c;并且主线程需要等待所有子线程执行完毕后再进行汇总的场景。在 CountDownLatch 出现之前一般都使用线程的join()方法来实现这一点&#xff0c;但是 join 方法不够灵活&…

jq实现网站-点击标签,添加到一个盒子中,再次点击去掉该标签

实现效果&#xff1a; 代码逻辑&#xff1a; 首先使用hasClass()方法判断点击的标签是否已经存在于盒子中。如果标签已经存在于盒子中&#xff0c;则使用removeClass()方法移除标签的’active’类名&#xff0c;并使用filter()方法找到盒子中与点击的标签文本相同的元素&#…

CAN总线(三)CAN总线链路层的三个标准

1、高速CAN总线 ISO 11898-2中定义了通信速率为125Kbps~1Mbps的高速闭环CAN通信标准,当通信总线长度≤40米,最大通信速率可达到1Mbps,高速闭环CAN(高速CAN)通信如下图所示: 1.1、电气特性 高速CAN总线上为显性电平(逻辑0)时,CAN_H为3.5V、CAN_L为1.5V,此时电压差是…

Qt应用开发——下载安装和HelloWorld

目录 1、下载和安装 2、HelloWorld 1、下载和安装 工欲善其事&#xff0c;必先利其器。第一步环境安装好是必要的过程。Qt 在23年4月份已经更新到了6.5.0&#xff0c;相对于其他的工具&#xff0c;Qt不断在维护升级这一点就非常的友好&#xff0c;这里对版本的迭代更新内容不…

由变上限积分求导到随机变量的概率分布

变上限积分求导书推导 推导过程根据导数的定义和积分的几何意义&#xff0c;看图&#xff1a; 随机变量的概率密度推导 若随机变量x 在 &#xff08;负无穷&#xff0c;正无穷&#xff09;的区间上服从f(x)的概率密度&#xff0c;设y g(x), x h(y)&#xff0c;求y 的概率…

web前端开发工程师的工作职责(合集)

web前端开发工程师的工作职责1 职责&#xff1a; 1.Web前端功能设计、开发和实现&#xff0c;与后台工程师协作&#xff0c;完成数据交互、动态展现; 2.对UI设计的结果进行页面制作(CSS/css3xhtml[表情]ml5JS); 3.熟悉编写可复用的用户接口组件; 4.从视觉和易用性角度&…

Git 安装设置

一&#xff1a;介绍 Git 是一个开源的分布式版本控制系统&#xff0c;用于敏捷高效地处理任何或小或大的项目。 二&#xff1a;安装 安装 Git for Windows&#xff0c;网址&#xff1a;https://git-scm.com/ 选择安装组件&#xff1a; 上图红框内的选项是默认勾选的&#xff…

设备集中监控,半导体CMS系统的优势解析

设备集中监控是半导体制造企业中的一项重要任务。传统的设备管理往往存在着分散的监控系统和孤立的报警中心的问题&#xff0c;给企业管理带来了一系列的挑战。而半导体CMS系统的出现&#xff0c;为企业解决了这些问题&#xff0c;并带来了明显的优势。 半导体CMS系统实现了设备…

初识mysql数据库之复合查询

目录 一、多表查询的概念 二、笛卡尔积 1. 笛卡尔积的概念 2. 笛卡尔积使用案例 2.1 显示雇员名、雇员工资以及所在部门的名字 2.2 显示部门号为10的部门名&#xff0c;员工名和工资 2.3 显示所有员工的姓名、工资和工资级别 3. 自连接 3.1 自连接的概念 3.2 自连接案…

idea 中的 pom.xml 文件变为灰色

idea 中的 pom.xml 文件变为灰色被忽略掉了 可能是新建 Module 之前创建了同名 Module&#xff0c; 并进行删除&#xff0c;idea 自动认为该排除此 Module 解决方法&#xff1a; 我们只要到 File → Settings → Build,Execution,Deployment →Ignored Files&#xff0c; …

数据结构(王道)——栈

一、栈的定义&#xff1a; 二、栈的基本操作&#xff1a; 对于栈的出栈顺序的理解&#xff1a; 栈总结&#xff1a; 三、顺序栈 栈的基本操作&#xff1a; 静态方式创建栈&#xff1a; 初始化&#xff1a; 进栈&#xff08;插入&#xff09;&#xff1a; 出栈&#xff08;删除&…

MFC扩展库BCGControlBar Pro v33.5新版亮点 - 其他增强功能

BCGControlBar库拥有500多个经过全面设计、测试和充分记录的MFC扩展类。 我们的组件可以轻松地集成到您的应用程序中&#xff0c;并为您节省数百个开发和调试时间。 BCGControlBar专业版 v33.5已正式发布了&#xff0c;此版本包含了Ribbon&#xff08;功能区&#xff09;自定义…

可以写进简历的软件测试电商项目(超详细版),不进来get一下?

前言 说实话&#xff0c;在找项目的过程中&#xff0c;我下载过&#xff08;甚至付费下载过&#xff09;N多个项目、联系过很多项目的作者&#xff0c;但是绝大部分项目&#xff0c;在我看来&#xff0c;并不适合你拿来练习&#xff0c;它们或多或少都存在着“问题”&#xff…

JVM之内存与垃圾回收篇2

文章目录 3 运行时区域3.1 本地方法栈3.2 程序计数器3.3 方法区3.3.1 Hotspot中方法区的演进3.3.2 设置方法区内存大小 3.4 栈3.4.1 几个面试题 3.5 堆3.5.1 Minor GC、Major GC和Full GC3.5.2 使用分代思想的原因3.5.3 内存分配策略3.5.4 TLAB3.5.5 堆是不是分配对象存储的唯一…

一文带你玩转自定义类型

作者主页&#xff1a;paper jie的博客_CSDN博客 本文作者&#xff1a;大家好&#xff0c;我是paper jie&#xff0c;感谢你阅读本文&#xff0c;欢迎一建三连哦。 本文录入于《系统解析C语言》专栏&#xff0c;本专栏是针对于大学生&#xff0c;编程小白精心打造的。笔者用重金…

Exception 类的层次

所有的异常类是从 java.lang.Exception 类继承的子类。 Exception 类是 Throwable 类的子类。除了Exception类外&#xff0c;Throwable还有一个子类Error 。 Java 程序通常不捕获错误。错误一般发生在严重故障时&#xff0c;它们在Java程序处理的范畴之外。 Error 用来指示运…

4027: 网络覆盖

4027: 网络覆盖 题目内容 有 n n n 个基站&#xff0c;他们可以抽象成一条数轴上的 n n n 个点&#xff0c;其中第 i i i 个基站在数轴上 x i x_i xi​ 的位置。 现在给每个基站分配一个半径 r i r_i ri​&#xff0c;这样对于第 i i i 个基站&#xff0c;它就会用信号…

uniapp中refs获取打印是空对象{}的解决办法

场景复现 版本如下: "dcloudio/uni-app": "2.0.2-3080720230703001", "vue": "> 2.6.14 < 2.7", 开发中发现只要是view这些原始标签的ref都无法在任何地方获取到refs.xxx, 而组件标签如<myStep></myStep> 这种加ref…

魔百盒cm101s m8233 emmc 卡刷教程

1、下载适用于对应型号的电视盒子刷机&#xff1b; https://download.csdn.net/download/qq_25601345/88051654?spm1001.2014.3001.5501 2、将下载好的四个文件放入u盘&#xff08;FAT32格式、最好4/8G的u盘&#xff09; 3、将u盘插入机顶盒的靠近网口的Usb接口 4、用镊子短…

python头部信息、py头部信息、python头信息、py头信息、py文件头部

文章目录 可指定以下信息1. 文件编码&#xff1a;# -*- coding: utf-8 -*-&#xff08;指定文件的字符编码&#xff0c;通常为UTF-8。&#xff09;2. 文件说明&#xff1a;Author等 对文件的简要说明&#xff0c;可以包括作者、创建日期、修改日期等信息。3. 版本信息&#xff…