QT实现雷达图和摇杆图

简介: 小伙伴们大家好,之前我上传了一个资源(骗积分用的),但是没有效果图和博文与之对应,所以大家应该是都不敢下载的吧,先上资源链接 : 一个雷达图和一个摇杆图(方向可以根据你自己的需要增加)资源再上效果图。

QT雷达图和摇杆图

小伙伴们大家好,之前我上传了一个资源(骗积分用的),但是没有效果图和博文与之对应,所以大家应该是都不敢下载的吧,


先上资源链接 : 一个雷达图和一个摇杆图(方向可以根据你自己的需要增加)资源


再上效果图。


摇杆图

0f16e9b0947e4184a38c7b89c92601e0.gif

雷达图

image.gif


这个是项目对应的图片


接下来为了保证文章质量,介绍一下两个控件吧,首先说明这知识一个widget,并没有封装到Qt Designer内,如果你有兴趣可以自己加上封装。


摇杆图代码介绍

介绍一下代码吧,按照图上的顺序,先介绍这个摇杆图:


主要代码:

void RockingBar::drawRing(QPainter &painter)
{
    int r = radius_ - 20;
    painter.save();
    QColor color_1("#47D72D"); color_1.setAlpha(60);
    QPen pen(color_1);
    pen.setCapStyle(Qt::RoundCap);
    QRectF rect = QRectF(-r, -r, 2*r, 2*r);
    QPainterPath path;
    path.moveTo(cos(16 *M_PI / 180 ) * r, -sin(16 *M_PI / 180)*r);
    path.arcTo(rect, 15, -30);
    path.moveTo(cos(106 *M_PI / 180 ) * r, -sin(106 *M_PI / 180)*r);
    path.arcTo(rect, 105, -30);
    path.moveTo(cos(196 *M_PI / 180 ) * r, -sin(196 *M_PI / 180)*r);
    path.arcTo(rect, 195, -30);
    path.moveTo(cos(286 *M_PI / 180 ) * r, -sin(286 *M_PI / 180)*r);
    path.arcTo(rect, 285, -30);
    pen.setWidth(10);
    painter.setPen(pen);
    painter.drawPath(path);
    QRectF rect2 = QRectF(-r + 10, -r + 10, 2*r - 20, 2*r- 20);
    pen.setWidth(4);
    color_1.setAlpha(100);
    pen.setColor(color_1);
    painter.setPen(pen);
    painter.drawEllipse(rect2);
    painter.restore();
}
void RockingBar::drawDirection(QPainter &painter)
{
    painter.save();
    QColor color_1("#47D72D"); color_1.setAlpha(200);
    QPen pen(color_1);
    QPainterPath path;
    QVector<QPointF> points{
            { -5.0, -40.0},
            { 5.0, -40.0},
            { 0.0, -40 + 10 * cos(60)},
    };
    QVector<QPointF> points2{
            { -5.0, 40.0},
            { 5.0, 40.0},
            { 0.0, 40 - 10 * cos(60)},
    };
    QVector<QPointF> points3{
            { -40, 5.0},
            { -40, -5.0},
            { -40 - 10 * cos(120), 0.0},
    };
    QVector<QPointF> points4{
            { 40, 5.0},
            { 40, -5.0},
            { 40 + 10 * cos(120), 0.0},
    };
    QPolygonF triangle;
    triangle.append(points);//三点坐标
    QPolygonF triangle2;
    triangle2.append(points2);//三点坐标
    QPolygonF triangle3;
    triangle3.append(points3);//三点坐标
    QPolygonF triangle4;
    triangle4.append(points4);//三点坐标
    path.addPolygon(triangle);
    path.addPolygon(triangle2);
    path.addPolygon(triangle3);
    path.addPolygon(triangle4);
    painter.setPen(Qt::NoPen);
    painter.setBrush(Qt::green);
    painter.drawPath(path); //画三角形
    painter.restore();
}
void RockingBar::drawRocker(QPainter &painter)
{
    int r = 15;
    painter.save();
    painter.translate(rocker_center_);
    QColor color_1("#47D72D"); color_1.setAlpha(200);
    QPen pen(color_1);
    QRectF rect2 = QRectF(-r, -r, 2*r, 2*r);
    pen.setColor(color_1);
    painter.setPen(Qt::NoPen);
    painter.setBrush(color_1);
    painter.drawEllipse(rect2);
    pen.setWidth(1);
    color_1.setAlpha(120);
    pen.setColor(color_1);
    painter.setPen(pen);
    painter.setBrush(Qt::NoBrush);
    rect2 =  QRectF(-r -2, -r -2, 2*r+4, 2*r+4);
    painter.drawEllipse(rect2);
    painter.restore();
}
void RockingBar::mousePressEvent(QMouseEvent *event)
{
    mouse_pressed_ = true;
}
void RockingBar::mouseMoveEvent(QMouseEvent *event)
{
    if(!mouse_pressed_)
    {
        return;
    }
    int width = this->width() / 2;
    int height = this->height() /2;
    QPointF point;
    point.setX((event->pos().x() - width) / scale_);
    point.setY((event->pos().y() - height) / scale_);
    int distance = point.x() * point.x() + point.y() * point.y();
    if(distance > 47 * 47)
    {
        double scale = 47.0 / sqrt(distance) ;
        point *= scale;
    }
    rocker_center_ = point;
    update();
}
void RockingBar::mouseReleaseEvent(QMouseEvent *event)
{
    mouse_pressed_ = false;
    rocker_center_ = QPointF(0.0, 0.0);
    update();
}

我觉得我的函数名称挺明确的,怎么介绍呢,就不介绍了,直接看 函数名称应该是能理解的,drawDirection 现在是写死的,如果是自己使用的话,最好是根据圆的规则写成一个数量的成员变量。


雷达图代码介绍

再介绍这个雷达图,


主要代码:

#include "radargpu.h"
#include <QPainter>
#include <QtMath>
#include <QMouseEvent>
RadarGpu::RadarGpu(QWidget *parent)
    : QOpenGLWidget(parent)
{
    QSurfaceFormat format = QSurfaceFormat::defaultFormat();
    format.setSamples(6);
    setFormat(format);
    connect(&timer_, SIGNAL(timeout()), this, SLOT(timeout()));
    timer_.start(20);
}
RadarGpu::~RadarGpu()
{
}
void RadarGpu::mousePressEvent(QMouseEvent *event)
{
    int width = this->width() / 2;
    int height = this->height() /2;
    QPoint point;
    point.setX((event->pos().x() - width) / scale_);
    point.setY((event->pos().y() - height) / scale_);
    if(point.x() * point.x() + point.y() * point.y() > (83 * 83))
    {
        return;
    }
    points_.append(point);
}
void RadarGpu::timeout()
{
    rotate_radius_+=6;
    if(rotate_radius_ == 360)
    {
        rotate_radius_ = 0;
    }
    update();
}
void RadarGpu::paintGL()
{
    int width = this->width();
    int height = this->height();
    int side = qMin(width, height);
    QPainter painter(this);
    painter.setRenderHints(QPainter::Antialiasing, true);
    painter.setRenderHints(QPainter::TextAntialiasing, true);
    painter.translate(width / 2, height / 2);
    scale_ = side / 200.0;
    painter.scale(scale_, scale_);
    drawScale(painter);
    drawRing(painter);
    drawScaleNum(painter);
    drawScanArea(painter);
    drawTarget(painter);
}
void RadarGpu::drawScale(QPainter &painter)
{
    int radius = radius_-12;
    painter.save();
    QPen pen;
    pen.setCapStyle(Qt::RoundCap);
    painter.rotate(start_angle_);
    int steps = (long_scale_ * short_scale_);
    double angleStep = (360.0 - start_angle_ - end_angle_) / steps;
    //计算圆环对应大刻度范围索引
    int indexStart = steps * (double)ring_start_ / 100 + 1;
    int indexMid = steps * (double)ring_middle_ / 100 - 1;
    int indexEnd = steps * (double)ring_end_ / 100 + 1;
    int index = 0;
    for (int i = 0; i <= steps; i++)
    {
        if (i % short_scale_ == 0)
        {
            //根据所在圆环范围切换颜色
            if (index < indexStart)
            {
                pen.setColor(ring_start_color_);
            } else if (index < (indexStart + indexMid))
            {
                pen.setColor(ring_middle_color_);
            } else if (index < (indexStart + indexMid + indexEnd))
            {
                pen.setColor(ring_end_color_);
            }
            index++;
            pen.setWidthF(0.5);
            painter.setPen(pen);
            painter.drawLine(0, radius - 12, 0, radius);
        } else {
            pen.setWidthF(0.5);
            pen.setColor(QColor(0,255,255));
            painter.setPen(pen);
            painter.drawLine(0, radius - 5, 0, radius);
        }
        painter.rotate(angleStep);
    }
    painter.restore();
}
void RadarGpu::drawScaleNum(QPainter &painter)
{
    int radius = radius_- 6;
    painter.save();
    painter.setPen(text_color_);
    QFont font;
    font.setPixelSize(6);
    painter.setFont(font);
    double startRad = (360 - start_angle_ - 90) * (M_PI / 180);
    double deltaRad = (360 - start_angle_ - end_angle_) * (M_PI / 180) / long_scale_;
    for (int i = 0; i < long_scale_; i++)
    {
        double sina = qSin(startRad - i * deltaRad);
        double cosa = qCos(startRad - i * deltaRad);
        double value = 1.0 * i * ((max_value_ - min_value_) / long_scale_) + min_value_;
        QString strValue = QString("%1").arg((double)value, 0, 'f', precision_);
        double textWidth = painter.fontMetrics().width(strValue);
        double textHeight = painter.fontMetrics().height();
        double x = radius * cosa - textWidth / 2.0;
        double y = -radius * sina + textHeight / 2.0;
        painter.drawText(QPointF(x, y), strValue);
    }
    painter.restore();
}
void RadarGpu::drawRing(QPainter &painter)
{
    int r = radius_;
    painter.save();
    double scale = 1.0 / ring_nums_;
    for(int i = 0; i < ring_nums_; ++i)
    {
        r =  radius_ * (scale * i);
        painter.setPen(QPen(Qt::green, 1));
        painter.drawEllipse(-r, -r, r * 2, r * 2);
    }
    painter.setPen(QPen(Qt::green, 1));
    painter.drawLine(0, -r, 0, r);
    painter.drawLine(-r, 0, r, 0);
    painter.restore();
}
void RadarGpu::drawScanArea(QPainter &painter)
{
    // 画扫描区域
    int r = radius_ -11;
    painter.save();
    painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
    painter.rotate(rotate_radius_);
    QColor color_0("#47D72D"); color_0.setAlpha(200);
    QColor color_2("#47D72D"); color_2.setAlpha(0);
    //绘制扫描线
    painter.setPen(QPen(color_0, 0));
    painter.drawLine(QPoint(0, 0), QPoint(radius_ - 12, 0));
    //绘制扫描线拖尾
    QConicalGradient scanAreaGradient(QPoint(0, 0), 0);
    scanAreaGradient.setColorAt(0.0, color_0);
    scanAreaGradient.setColorAt(1. / 360, color_0);
    scanAreaGradient.setColorAt(120. / 360, color_2);
    painter.setPen(Qt::NoPen);
    painter.setBrush(scanAreaGradient);
    painter.drawPie(QRect(-r, -r, r*2, r*2), 0, 120 * 16);
    painter.restore();
}
void RadarGpu::drawTarget(QPainter &painter)
{
    painter.save();
    QColor color_0("#ffffff"); color_0.setAlpha(250);
    QColor color_4("#ffffff"); color_4.setAlpha(200);
    QColor color_1("#47D72D"); color_1.setAlpha(200);
    QColor color_2("#47D72D"); color_2.setAlpha(0);
    for (int i = 0; i < points_.count(); ++i)
    {
        painter.setPen(Qt::NoPen);
        QRadialGradient radialGradient(points_.at(i), 3, points_.at(i));
        radialGradient.setColorAt(0.0,color_0);
        radialGradient.setColorAt(0.1,color_4);
        radialGradient.setColorAt(0.2,color_1);
        radialGradient.setColorAt(1.0,color_2);
        painter.setBrush(radialGradient);
        painter.drawEllipse(points_.at(i).x()-3,points_.at(i).y()-3,6,6);
    }
    painter.restore();
}

我觉得我的函数名称已经可以代替介绍了,我传的代码都是加了注释的,不用担心看不懂哦,当然你要是完全没有基础则当我没说。


注:

雷达图比摇杆图稍微复杂一点,资源里面提供了两个版本的,资源里面还有一个汽车的仪表盘,没有显示出来.其实这种的绘制只要是一个能做出来之后后续的只要有样式应该是都不复杂,都可以实现的。


不需要每一个都看别人怎么写,应该是自己能理解的。要窥一斑而知全豹。

相关实践学习
部署Stable Diffusion玩转AI绘画(GPU云服务器)
本实验通过在ECS上从零开始部署Stable Diffusion来进行AI绘画创作,开启AIGC盲盒。
目录
相关文章
|
6月前
|
存储
QT图形视图框架绘制曲线图和Smith图
QT图形视图框架绘制曲线图和Smith图
115 0
用AItium Designer 14 绘制电路图
要使用Altium Designer 14绘制电路图,可以按照以下步骤进行操作: 1. 打开Altium Designer 14软件。 2. 创建一个新的工程:点击“File”(文件)菜单,选择“New”(新建),然后选择“Project”(工程)。在弹出的对话框中,选择一个合适的工程文件夹,并设置工程名称。 3. 在工程中创建一个新的电路图:在左侧的“Projects”(项目)窗格中,展开工程文件夹,右键点击“Schematic”(电路图)文件夹,选择“Add New to Project”(添加新文件到工程)。在弹出的对话框中,选择“Schematic”(电路图),然后设置电路图名称
207 0
|
7天前
|
Python
pyqt6 制作一个颜色调节器 01
本文介绍了一个使用 PyQt 制作的颜色调节器,通过滑动滚动条或旋钮来调整 RGB 三色,实现颜色的微调。具体步骤包括:1. 设计 UI 页面;2. 分析颜色调整逻辑;3. 将数据反馈到 UI 页面。最终实现了颜色随滑块变化而实时更新的效果。
18 1
|
移动开发 前端开发 C#
在Unity3D中实现热力图、风向图、温度图效果(Unity3D)
因一个任务要完成如何在Unity上面实现热力图的效果,所以百度了很久,发现资料很少,现在就把我总结的如何在Unity上面基于Canvas实现热力图效果的实现过程分享出来, 此前转载了一篇主要讲的是如何根据数据值,在Canvas上重新绘制RGBA的值,完成热力图的绘制,不过用的是H5写的,我修改了一下,用C#重写的
|
7天前
pyqt6 制作一个颜色调节器 02
本文介绍了如何使用PyQt6实现一个颜色调节器。首先创建了一个显示RGB颜色值变化的标签,然后通过三个旋钮(QDial)分别控制红、绿、蓝三种颜色的值,并在旋钮下方显示当前值。通过嵌套布局实现了旋钮和标签的排列,最终实现了颜色值的变化和显示。完整代码也一并提供。
20 0
|
5月前
|
机器学习/深度学习 图形学
神笔马良画出三维世界,基于线稿的3D生成编辑方法SketchDream来了
【6月更文挑战第10天】研究人员推出SketchDream系统,将手绘草图与文本描述转化为3D模型,简化了3D内容创作过程。该系统基于深度学习的多模态生成模型,结合草图和文本信息,实现高质量3D生成与编辑。尽管有局限性,如依赖预训练模型和对复杂编辑任务的处理能力,SketchDream在3D生成和编辑方面表现出色,降低了3D建模的门槛。[论文链接](https://arxiv.org/pdf/2405.06461)
78 1
|
6月前
|
存储 数据可视化 关系型数据库
绘制圆环图/雷达图/星形图/极坐标图/径向图POLAR CHART可视化分析汽车性能数据
绘制圆环图/雷达图/星形图/极坐标图/径向图POLAR CHART可视化分析汽车性能数据
|
6月前
|
存储 数据可视化
创建乐高版马赛克图
创建乐高版马赛克图
94 0
|
C++
c++搭建的车道线和路牌的识别系统 使用qt界面
c++搭建的车道线和路牌的识别系统 使用qt界面
59 0
|
C++ Python
C++ VTK鼠标网格表面绘制曲线
C++ VTK鼠标网格表面绘制曲线
441 0
C++ VTK鼠标网格表面绘制曲线