QT实现雷达扫描

完整版链接:https://blog.csdn.net/m0_51415606/article/details/131998314

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

  • 2
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 使用Qt实现雷达扫描图,可以使用以下代码:// 定义变量 QPen pen; QBrush brush; QRectF rect; QPainter painter;// 设置画笔颜色 pen.setColor(Qt::blue);// 设置画刷 brush.setColor(Qt::green); brush.setStyle(Qt::SolidPattern);// 创建QPainter对象 painter.begin(this);// 设置画笔 painter.setPen(pen);// 绘制雷达扫描图 for(int i = 0; i < 360; i++){ rect.setX(i); rect.setY(i); rect.setWidth(10); rect.setHeight(10); painter.fillRect(rect, brush); }// 结束绘制 painter.end(); ### 回答2: 实现雷达扫描图的关键是绘制雷达扫描效果和目标点的显示效果。使用Qt可以通过继承QPainter类来进行绘图操作。下面是一个简单的实现: ```cpp #include <QtWidgets/QApplication> #include <QtWidgets/QWidget> #include <QtGui/QPainter> #include <QtCore/QTimer> #include <QtCore/QPointF> #include <QtCore/QVector> class RadarWidget : public QWidget { public: RadarWidget(QWidget *parent = nullptr) : QWidget(parent), angle(0) { // 设置窗口尺寸 setFixedSize(300, 300); // 设置定时器,每隔一段时间进行重绘 QTimer *timer = new QTimer(this); connect(timer, SIGNAL(timeout()), this, SLOT(update())); timer->start(10); } protected: void paintEvent(QPaintEvent *event) override { QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing, true); int radius = qMin(width(), height()) / 2; int centerX = width() / 2; int centerY = height() / 2; // 绘制雷达扫描效果 painter.setPen(QPen(Qt::green, 2)); painter.setBrush(Qt::NoBrush); painter.drawEllipse(centerX - radius, centerY - radius, radius * 2, radius * 2); painter.drawLine(centerX, centerY, centerX + radius * qCos(qDegreesToRadians(angle)), centerY + radius * qSin(qDegreesToRadians(angle))); // 绘制目标点 painter.setPen(QPen(Qt::red, 5)); painter.setBrush(Qt::red); for (const QPointF &point : targetPoints) { // 计算目标点在雷达中的位置 int x = centerX + point.x() * radius; int y = centerY + point.y() * radius; painter.drawEllipse(x - 2, y - 2, 4, 4); } angle = (angle + 1) % 360; // 更新扫描角度 } private: int angle; QVector<QPointF> targetPoints{{0.3, 0.3}, {0.5, -0.2}, {-0.4, 0.1}, {-0.6, -0.5}}; }; int main(int argc, char *argv[]) { QApplication app(argc, argv); RadarWidget radarWidget; radarWidget.show(); return app.exec(); } ``` 以上代码创建了一个`RadarWidget`类,继承自`QWidget`,重写了`paintEvent`函数来绘制雷达扫描图。主要的绘图操作包括绘制雷达扫描效果和绘制目标点。在`main`函数中创建了`RadarWidget`类的对象,并进行显示。运行程序后可以看到一个简单的雷达扫描图,目标点会随着扫描角度的改变而在雷达上显示。 ### 回答3: Qt实现雷达扫描图主要通过继承QWidget并重写paintEvent()函数来实现。具体的代码如下: ```cpp #include <QtWidgets> class RadarWidget : public QWidget { public: RadarWidget(QWidget *parent = nullptr) : QWidget(parent) { startTimer(100); // 设置定时器,每100ms刷新一次 } protected: void paintEvent(QPaintEvent *event) override { Q_UNUSED(event); // 获取绘图设备 QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing); // 抗锯齿 // 获取雷达扫描图的中心坐标和半径 int centerX = width() / 2; int centerY = height() / 2; int radius = qMin(centerX, centerY) - 10; // 绘制雷达扫描图的背景 painter.setBrush(QColor(200, 200, 200)); painter.drawEllipse(centerX - radius, centerY - radius, radius * 2, radius * 2); // 绘制雷达扫描线 painter.setPen(QPen(Qt::green, 2, Qt::SolidLine)); painter.drawLine(QPointF(centerX, centerY), QPointF(centerX + radius * cos(radarAngle), centerY + radius * sin(radarAngle))); // 更新雷达扫描角度 radarAngle += radianStep; // 设置雷达扫描步长和角度范围,可自行调整 radianStep = 3.1416 / 180 * 5; // 步长为5度 radarAngle = radarAngle < 2 * 3.1416 ? radarAngle : 0; // 范围为0~2π // 强制更新 update(); } void timerEvent(QTimerEvent *event) override { Q_UNUSED(event); // 定时器触发时重新绘制 update(); } private: float radarAngle = 0; // 雷达扫描角度 float radianStep = 3.1416 / 180 * 5; // 步长为5度 }; int main(int argc, char *argv[]) { QApplication app(argc, argv); RadarWidget radarWidget; radarWidget.resize(400, 400); radarWidget.show(); return app.exec(); } ``` 代码中通过重写paintEvent()函数绘制雷达扫描图的背景和扫描线。然后通过定时器不断刷新,更新雷达扫描角度,并在paintEvent()函数中绘制扫描线。最后在main()函数中创建RadarWidget对象并显示出来。实际运行这段代码可以看到一个简单的雷达扫描图。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值