qt仿雷达图扫描效果

2 篇文章 0 订阅
1 篇文章 0 订阅

话不多说,上代码。

头文件:

#ifndef CRADAR_H
#define CRADAR_H

/*************************************************
描述: 仿雷达扫描效果
**************************************************/

#include <QWidget>
#include "QPainter"
#include <QJsonObject>

class CRadar : public QWidget
{
    Q_OBJECT
public:
    explicit CRadar(QWidget *parent = nullptr);
    QVector<QJsonObject> mb_points;        //目标点
    int home_dir;   //指北偏移角度

protected:
    void paintEvent(QPaintEvent *event);    //绘制事件
    void resizeEvent(QResizeEvent *event);  //大小重置事件
    void timerEvent(QTimerEvent *event);    //定时器事件
private:
    QRect         m_drawArea;      //绘制区域
    int           m_pieRotate;     //扇形旋转区域
    int           m_timerId;       //定时器ID
    int           m_pointTimerId;  //变更点定时器
    int           m_nSpeed;        //速度
    QList<QPoint> m_points;        //绘制点
    QList<int>    m_pointsAlapha;  //绘制点颜色alapha值
    QPoint CustomRotate(QPointF point,qreal from_angle,qreal rotate);
    QList<QPointF> trans(int angle,float len1,float len2);
};

#endif // CRADAR_H

cpp文件:

#include "cradar.h"
#include <QPainter>
#include <QtMath>
#include <QTimerEvent>
#include <QConicalGradient>
#include <qDebug>
#include "math.h"
CRadar::CRadar(QWidget *parent) : QWidget(parent)
{
    //初始化
    m_pieRotate = 0;
    m_timerId = -1;
    m_nSpeed = 50;
    m_pointsAlapha<<100<<100<<100<<100<<100;

    //启动定时器
    m_timerId = startTimer(m_nSpeed);
    //m_pointTimerId = startTimer(1200);
}

void CRadar::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);

    //抗锯齿
    painter.setRenderHint(QPainter::Antialiasing);

    //背景
    //    painter.fillRect(rect(),QColor(15,45,188));

    //边长
    int len = m_drawArea.width()-30;

    //底盘(x轴、y轴和4个圆)
    painter.setPen(QPen(Qt::green));
    //圆
    painter.drawEllipse(m_drawArea.center(),len*21/40,len*21/40);
    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);

    int fontSize = 15;
    int p_crosses = 3;//十字架数量
    //坐标轴
    for(int i=0; i < p_crosses; i++)
    {
        QLineF line1,line2;
        float angle = (static_cast<float>(i) * 90.0) / (static_cast<float>(p_crosses));
        line1.setP1( m_drawArea.center() );
        line1.setLength( len/2);

        QRectF textRect(0, 0, 4 * fontSize, fontSize + 2);

        for(int c = 0; c < 4; c++)
        {
            line1.setAngle(angle + c*90.0 + 90.0);
            painter.drawLine(line1);
            line2 = QLineF(line1);
            line2.setLength(len/2+6.5 );
            textRect.moveCenter(line2.p2());
            if(i > 0){
                painter.drawText( textRect, Qt::AlignCenter, QString("%1").arg((int)(360 - (c*90 ) - angle) , 3 , 10));
            }else
            {
                if(c == 0)
                {
                    painter.drawText( textRect, Qt::AlignCenter,QString("0"));
                }
                else if(c == 1)
                {
                    painter.drawText( textRect, Qt::AlignCenter, QString("270"));
                }
                else if(c == 2)
                {
                    painter.drawText( textRect, Qt::AlignCenter, QString("180"));
                }
                else if(c == 3)
                {
                    painter.drawText( textRect, Qt::AlignCenter, QString("90"));
                }
            }
        }
    }

    //刻度
    int num=1;
    float len1 = len*21/40;
    float len2;
    QList<QPointF> pointArr;
    for(int i=0;i<360;i++){
        num++;
        //10的倍数刻度要略长
        if(num==11){
            len2 = len/2;
            pointArr = trans(i,len1,len2);
            num=1;
        }else{
            len2 = len*41/80;
            pointArr = trans(i,len1,len2);
        }
        //画刻度
        painter.drawLine(pointArr.at(0),pointArr.at(1));
    }
    //转动部分
    //---//线
    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);
    QColor linecolor(20,232,147);//设置颜色
    painter.setPen(QPen(Qt::green));
    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(32, 255, 77,100)); //从渐变角度开始0.5 - 0.75为扇形区域,由于Int类型计算不精确,将范围扩大到0.4-0.8
    gradient.setColorAt(0.8,QColor(32, 255, 77,0));
    painter.setBrush(QBrush(gradient));
    painter.setPen(Qt::NoPen);
    painter.drawPie(m_drawArea,m_pieRotate*16,90*16);
    QPixmap pixmap_n(":/images/icon-red.png");

    //绘制本舰指北方向
    QPixmap pixmap3(":/images/jiantou.png");
    painter.translate(m_drawArea.center());
    painter.rotate(-home_dir);//旋转角度
    QPoint point = CustomRotate(QPoint(len/2,0),0,-90);// 使图片方向不变
    painter.drawPixmap(point.x()-pixmap3.width(),point.y()-pixmap3.height(),pixmap3);
    painter.resetTransform();

    QPixmap pixmap2(":/images/mubiao.png");

    //绘制目标点
    for(int i = 0; i < mb_points.size(); i++)
    {
        painter.save();
        int x_mb= m_drawArea.center().x()+static_cast<int>(mb_points.at(i).value("x").toDouble());
        int y_mb = m_drawArea.center().y()-static_cast<int>(mb_points.at(i).value("h").toDouble());
        //背景图恢复正常指向
        int dir_mb = (mb_points.at(i).value("dir").toDouble())-180;
        int id_mb = (mb_points.at(i).value("id").toInt());
        //绘制目标点名称
        painter.setPen(QColor(Qt::white));
        painter.drawText(x_mb-20,y_mb+20,QString::number(id_mb));

        //绘制目标航向
        painter.translate(QPointF(x_mb,y_mb));
        painter.rotate(dir_mb);//旋转角度
        painter.drawPixmap(QPoint(-8,-8),pixmap2);
        painter.restore();
    }
}
QPoint CRadar::CustomRotate(QPointF point,qreal from_angle,qreal rotate)
{
    qreal PI=3.141592653589;
    QPointF Tmp;
    qreal arc = (rotate-from_angle)/180*PI;
    qreal Length = qSqrt(point.x()*point.x() +point.y()*point.y());
    Tmp.setX(Length*qCos(arc));
    Tmp.setY(Length*qSin(arc));
    return Tmp.toPoint();
}
//将角度转为两个坐标点
QList<QPointF> CRadar::trans(int angle,float len1,float len2)
{
    QList<QPointF> list;
    QPointF ptResult1(m_drawArea.center());
    QPointF ptResult2(m_drawArea.center());
    //[角度转弧度]
    float rad = qDegreesToRadians(static_cast<float>(angle));

    ptResult1.setX(m_drawArea.center().x() + len1 * qSin(static_cast<qreal>(rad)));
    ptResult1.setY(m_drawArea.center().y() - len1 * qCos(static_cast<qreal>(rad)));
    list.append(ptResult1);
    ptResult2.setX(m_drawArea.center().x() + len2 * qSin(static_cast<qreal>(rad)));
    ptResult2.setY(m_drawArea.center().y() - len2 * qCos(static_cast<qreal>(rad)));
    list.append(ptResult2);
    return list;
}
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);
}

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组件,然后放入widget中,

CRadar radar = new CRadar(this);
//我是直接放入了一个水平布局中
ui->horizontalLayout_26->addWidget(radar);

当雷达图里的目标点需要更换时,把存储目标点的线性链表先清空再重新赋值:

//清空原有目标信息
radar->mb_points.clear();
//targetList存储的是目标坐标等信息
 if(targetList.length()<=0) return;
float m_PI = 3.1415926;
//home_dir是指北偏移角度
 radar->home_dir = navigate->m_home.m_navigate.m_direction;
 for(int i=0;i<targetList.length();i++){
   //目标行驶方向
   float m_dir=targetList.at(i).direction;
    //目标坐标
   float hig = targetList.at(i).y;//y坐标
   float mb_x =targetList.at(i).x;//x坐标

   QJsonObject jsonobj;
   jsonobj.insert("x",mb_x);
   jsonobj.insert("h",hig);
   jsonobj.insert("dir",m_dir);
   jsonobj.insert("id", targetList.at(i).m_id);//目标id
   radar->mb_points.append(jsonobj);
}

  • 1
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
QT雷达波束扫描是一种用于显示雷达扫描结果的形化工具。它能够以表的形式直观地展示出雷达接收到的目标信息。通常,雷达波束扫描被用于显示雷达探测到的目标的位置、速度和方向等信息。 QT是一个跨平台的应用程序开发框架,它提供了丰富的形化界面设计工具和库函数。通过使用QT,我们可以方便地创建和绘制雷达波束扫描雷达波束扫描通常由两个部分组成:雷达位置和目标信息雷达位置显示了雷达的位置和扫描范围,通常以雷达位置为中心,以圆或扇形的方式表示扫描范围。目标信息则显示了雷达探测到的目标的位置和其他相关信息。这些目标通常用点或其他形状表示,并配有标签来标识其属性。通过不同的颜色或形状,目标信息可以提供更多的目标属性信息,例如目标的速度、方向或类型等。 QT雷达波束扫描能够实时地从雷达接收到的数据中生成,并能够动态地更新表。该表常用于航空、海洋等领域中的目标监测和追踪任务。通过观察雷达波束扫描,操作人员可以更加直观地了解目标的状态和动态变化,从而辅助决策和操作。 总的来说,QT雷达波束扫描是一种能够以表形式展示雷达探测结果的工具,具有直观、实时更新等特点,广泛应用于目标监测和追踪任务中。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值