Qt雷达图,多线程生成警示数据

发布于:2025-04-17 ⋅ 阅读:(21) ⋅ 点赞:(0)

        Qt画的雷达图demo,多线程不断生成警示数据

       运行结果

雷达

        实现代码 

         h文件

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QThread>
#include <QTimer>
#include <QVector>
#include <QPointF>

class AnomalyDetectionThread;

class RadarChart : public QWidget
{
    Q_OBJECT
public:
    explicit RadarChart(QWidget *parent = nullptr);
    ~RadarChart();

protected:
    void paintEvent(QPaintEvent *event) override;

private slots:
    void onAnomalyDetected(int angle);
    void updateScanAngle();

private:
    void drawRadarBackground(QPainter &painter);
    void drawScanLine(QPainter &painter);
    void drawAnomalies(QPainter &painter);

    AnomalyDetectionThread *anomalyThread;
    QVector<int> anomalies;
    QTimer *scanTimer;
    int scanAngle;
};

class AnomalyDetectionThread : public QThread
{
    Q_OBJECT
public:
    AnomalyDetectionThread(QObject *parent = nullptr);

signals:
    void anomalyDetected(int angle);

protected:
    void run() override;
};

#endif // WIDGET_H

        c文件

#include "widget.h"
#include <QPainter>
#include <QtMath>
#include <QRandomGenerator>

RadarChart::RadarChart(QWidget *parent) : QWidget(parent)
{
    setFixedSize(400, 400);
    // 启动异常检测线程
    anomalyThread = new AnomalyDetectionThread(this);
    connect(anomalyThread, &AnomalyDetectionThread::anomalyDetected, this, &RadarChart::onAnomalyDetected);
    anomalyThread->start();

    // 初始化扫描定时器
    scanTimer = new QTimer(this);
    connect(scanTimer, &QTimer::timeout, this, &RadarChart::updateScanAngle);
    scanTimer->start(20); // 每 20 毫秒更新一次扫描角度
    scanAngle = 0;
}

RadarChart::~RadarChart()
{
    anomalyThread->requestInterruption();
    anomalyThread->wait();
}

void RadarChart::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event);
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);

    // 绘制雷达图背景
    drawRadarBackground(painter);

    // 绘制扫描线
    drawScanLine(painter);

    // 绘制检测到的异常
    drawAnomalies(painter);
}

void RadarChart::onAnomalyDetected(int angle)
{
    anomalies.append(angle);
    if (anomalies.size() > 10) { // 限制异常点的数量
        anomalies.removeFirst();
    }
    update();
}

void RadarChart::updateScanAngle()
{
    scanAngle = (scanAngle + 2) % 360; // 每次增加 2 度
    update();
}

void RadarChart::drawRadarBackground(QPainter &painter)
{
    int centerX = width() / 2;
    int centerY = height() / 2;
    int radius = qMin(width(), height()) / 2 - 20;

    // 绘制雷达图的网格
    painter.setPen(QPen(Qt::cyan, 1));
    for (int i = 1; i <= 5; ++i) {
        int currentRadius = radius * i / 5;
        painter.drawEllipse(centerX - currentRadius, centerY - currentRadius, 2 * currentRadius, 2 * currentRadius);
    }

    // 绘制雷达图的射线
    painter.setPen(QPen(Qt::cyan, 2));
    for (int i = 0; i < 360; i += 30) {
        double rad = qDegreesToRadians(static_cast<double>(i));
        int x = centerX + radius * qCos(rad);
        int y = centerY + radius * qSin(rad);
        painter.drawLine(centerX, centerY, x, y);
    }
}

void RadarChart::drawScanLine(QPainter &painter)
{
    int centerX = width() / 2;
    int centerY = height() / 2;
    int radius = qMin(width(), height()) / 2 - 20;

    double rad = qDegreesToRadians(static_cast<double>(scanAngle));
    int x = centerX + radius * qCos(rad);
    int y = centerY + radius * qSin(rad);

    painter.setPen(QPen(Qt::yellow, 2));
    painter.drawLine(centerX, centerY, x, y);
}

void RadarChart::drawAnomalies(QPainter &painter)
{
    int centerX = width() / 2;
    int centerY = height() / 2;
    int radius = qMin(width(), height()) / 2 - 20;

    painter.setPen(QPen(Qt::red, 5));
    for (int angle : anomalies) {
        double rad = qDegreesToRadians(static_cast<double>(angle));
        int x = centerX + radius * qCos(rad);
        int y = centerY + radius * qSin(rad);
        painter.drawPoint(x, y);
    }
}

AnomalyDetectionThread::AnomalyDetectionThread(QObject *parent) : QThread(parent)
{
}

void AnomalyDetectionThread::run()
{
    while (!isInterruptionRequested()) {
        int angle = QRandomGenerator::global()->bounded(360);
        emit anomalyDetected(angle);
        msleep(500); // 每 500 毫秒生成一个新的异常点
    }
}

 希望对大家有所帮助


网站公告

今日签到

点亮在社区的每一天
去签到