简易雷达

效果图
在这里插入图片描述
头文件

#ifndef QWHRADARSCAN_H
#define QWHRADARSCAN_H

#include <QWidget>
#include <QPaintEvent>
#include <QPainter>
#include <QList>
#include <QTimer>
#include <QColor>

class QWHRadarScan : public QWidget
{
    Q_OBJECT
public:
    struct Mark
    {
        int posX;
        int posY;
        int angle;
        QString name;
    };

    explicit QWHRadarScan(QWidget *parent = nullptr);
    ~QWHRadarScan();

    void setMarks(QList<Mark> marks);
    QList<Mark> getMarks();
protected:
    void paintEvent(QPaintEvent *event);
    void drawBgArcs(QPainter *painter);
    void drawScale(QPainter *painter);
    void drawScaleNum(QPainter *painter);
    void drawMarks(QPainter *painter);
    void drawScan(QPainter *painter);
private:
    double degreeToArc(double angle);
    double distance(QPointF p1, QPointF p2);
private slots:
    void Scanning();
signals:


public slots:
private:
    int m_arcs;                 //圆弧数量
    int m_curAngle;             //当前扫描角度
    int m_scanAngle;            //扫描扇区角度
    bool m_loop;                //是否进入下次循环
    bool m_refresh;             //下次扫描是否清空从来
    bool m_showText;            //是否显示目标名称
    bool m_showScale;           //是否显示刻盘
    int m_kilometers;           //雷达扫描半径:千米
    int m_scaleRotate;          //雷达外围刻度旋转角度,正北方向刻度

    QColor m_markColor;         //目标颜色
    QColor m_arcColor;          //弧线和扫描区域颜色
    QColor m_bgColor;           //背景颜色
    QColor m_scaleColor;        //刻盘颜色

    QList<Mark> m_listMarks;    //存储目标
    QTimer *m_timer;            //定时器绘制
};

#endif // QWHRADARSCAN_H

核心代码

void QWHRadarScan::paintEvent(QPaintEvent *event)
{
    int width = this->width();
    int height = this->height();
    int side = qMin(width, height);

    QPainter painter(this);
    painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
    painter.translate(width / 2, height / 2);
    painter.scale(side / 200, side / 200);

    //绘制背景
    drawBgArcs(&painter);
    if (m_showScale)
    {
        //绘制刻度线
        drawScale(&painter);
        //绘制刻度
        drawScaleNum(&painter);
    }
    //绘制标记
    drawMarks(&painter);
    //绘制扫描
    drawScan(&painter);
}

void QWHRadarScan::drawBgArcs(QPainter *painter)
{
    painter->save();

    painter->setBrush(m_bgColor);
    painter->drawRect(-100, -100, 200, 200);

    QPen pen(Qt::green, 1, Qt::SolidLine);
    painter->setPen(pen);
    QFont font;
    font.setPixelSize(5);
    painter->setFont(font);

    for (int i = 1; i <= m_arcs; i++)
    {
        int radius = i * 84.0 / m_arcs;
        QRect rect(-radius, -radius, radius * 2, radius * 2);
        painter->drawArc(rect, 0 * 16, 360 * 16);
    }

    painter->drawLine(0, -84, 0, 84);
    painter->drawLine(-84, 0, 84, 0);

#if 0
    //显示距离
    for (int i = 1; i <= 5; i++)
    {
        QString text = QString::number(m_kilometers * i * 1.0 / 5, 'f', 0);
        int textWidth = fontMetrics().width(text);
        int textHeight = fontMetrics().height();
        painter->drawText(-textWidth / 2, 84.0 * i / 5 - textHeight / 2, textWidth, textHeight, Qt::AlignCenter, text);
    }
#endif
    painter->restore();
}

void QWHRadarScan::drawScale(QPainter *painter)
{
    painter->save();

    int radius = 86;
    QPen pen(m_scaleColor);
    int rotate = 180 + 360 - m_scaleRotate - 1;
    painter->rotate(rotate);

    for (int i = 0; i < 360; i++)
    {
        painter->rotate(1);
        if (i % 5 == 0)
        {
            if (i % 10 == 0)
            {
                pen.setWidthF(0.7);
                painter->setPen(pen);
                painter->drawLine(QPoint(0, 84), QPoint(0, radius + 2));
            }
            else
            {
                pen.setWidthF(0.5);
                painter->setPen(pen);
                painter->drawLine(QPoint(0, 84), QPoint(0, radius + 1));
            }
        }
        else
        {
            pen.setWidthF(0.4);
            painter->setPen(pen);
            painter->drawLine(QPoint(0, 84), QPoint(0, radius));
        }
    }

    painter->restore();
}

void QWHRadarScan::drawScaleNum(QPainter *painter)
{
    painter->save();

    int radius = 93;
    QPen pen(m_scaleColor);
    QFont font;
    font.setPixelSize(4);
    painter->setFont(font);

    int northAngle = 90;
    int text = m_scaleRotate;
    for (int i = m_scaleRotate; i < m_scaleRotate + 360; i++)
    {
        if (i % 10 == 0)
        {
            int x = radius * qCos(degreeToArc(northAngle));
            int y = radius * qSin(degreeToArc(northAngle));
            QPoint p(x, y);
            text = (text >= 360) ? 0 : text;
            QString strText = QString::number(text);
            int textWidth = fontMetrics().width(strText);
            int textHeight = fontMetrics().height();
            painter->setPen(pen);
            painter->drawText(x - textWidth / 8, -y + textHeight / 15, strText);
        }
        northAngle -= 1;
        text++;
    }

    pen.setColor(Qt::white);
    font.setPixelSize(6);
    painter->setFont(font);
    painter->setPen(pen);
    painter->drawText(QPointF(-1, -91), QString("N"));
    painter->drawText(QPointF(92, 2), QString("E"));
    painter->drawText(QPointF(-1, 94), QString("S"));
    painter->drawText(QPointF(-96, 2), QString("W"));

    painter->restore();
}

void QWHRadarScan::drawMarks(QPainter *painter)
{
    painter->save();

    if (m_listMarks.count() <= 0)
    {
        return;
    }
    QPen pen(m_markColor, 5, Qt::SolidLine);
    pen.setCapStyle(Qt::RoundCap);
    painter->setPen(pen);

    //扫描扇区(浓) 对应的 坐标轴角度
    double realAngle = 360 - m_curAngle;
    if (m_loop)
    {
        //第一圈扫描完后清空标记,重新显示
        if (m_refresh)
        {
            for (int i = 0; i < m_listMarks.count(); i++)
            {
                QPoint p = QPoint(m_listMarks[i].posX, m_listMarks[i].posY);
                if (distance(p, QPoint(0, 0)) < m_kilometers)
                {
                    if (m_listMarks[i].angle > realAngle)
                    {
                        //绘图区域半径为100, 选取84长度作为雷达扫描的绘图区域
                        int posX = m_listMarks[i].posX * 1.0 / m_kilometers * 84.0;
                        int posY = -m_listMarks[i].posY * 1.0 / m_kilometers * 84.0;
                        painter->drawPoint(posX, posY);

                        if (m_showText)
                        {
                            int width = fontMetrics().width(m_listMarks[i].name);
                            int height = fontMetrics().height();
                            painter->drawText(posX - width / 2, posY - height / 4, m_listMarks[i].name);
                        }
                    }
                }
            }
        }
        else
        {
            for (int i = 0; i < m_listMarks.count(); i++)
            {
                QPoint p = QPoint(m_listMarks[i].posX, m_listMarks[i].posY);
                if (distance(p, QPoint(0, 0)) < m_kilometers)
                {
                    int posX = m_listMarks[i].posX * 1.0 / m_kilometers * 84.0;
                    int posY = -m_listMarks[i].posY * 1.0 / m_kilometers * 84.0;
                    painter->drawPoint(posX, posY);

                    if (m_showText)
                    {
                        int width = fontMetrics().width(m_listMarks[i].name);
                        int height = fontMetrics().height();
                        painter->drawText(posX - width / 2, posY - height / 4, m_listMarks[i].name);
                    }
                }
            }
        }
    }
    else
    {
        for (int i = 0; i < m_listMarks.count(); i++)
        {
            QPoint p = QPoint(m_listMarks[i].posX, m_listMarks[i].posY);
            if (distance(p, QPoint(0, 0)) < m_kilometers)
            {
                if (m_listMarks[i].angle > realAngle)
                {
                    int posX = m_listMarks[i].posX * 1.0 / m_kilometers * 84.0;
                    int posY = -m_listMarks[i].posY * 1.0 / m_kilometers * 84.0;
                    painter->drawPoint(posX, posY);

                    if (m_showText)
                    {
                        int width = fontMetrics().width(m_listMarks[i].name);
                        int height = fontMetrics().height();
                        painter->drawText(posX - width / 2, posY - height / 4, m_listMarks[i].name);
                    }
                }
            }
        }
    }

    painter->restore();
}

void QWHRadarScan::drawScan(QPainter *painter)
{
    painter->save();
    painter->rotate(m_curAngle);

    QColor color1(m_arcColor);
    color1.setAlpha(255);
    QColor color2(m_arcColor);
    color2.setAlpha(0);

    QConicalGradient cg;
    cg.setColorAt(0, color1);
    cg.setColorAt(m_scanAngle * 1.0 / 360 , color2);
    painter->setBrush(cg);

    QRect rect(-84, -84, 168, 168);
    painter->setPen(Qt::NoPen);
    painter->drawPie(rect, 0 * 16, m_scanAngle * 16);

    painter->restore();
}
发布了228 篇原创文章 · 获赞 44 · 访问量 10万+

猜你喜欢

转载自blog.csdn.net/qq_40945965/article/details/100168017