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盲盒。
目录
相关文章
|
前端开发
Silverlight 雷达图和一种特殊泡泡画法
原文:Silverlight 雷达图和一种特殊泡泡画法   自上次发了雷达图,也没怎么说一下。 这次又做了一种图,继续共享一下,就是以一个点为中心,周围绕着几个点,用一个箭头与中心相连并带有某些信息。
984 0
|
移动开发 前端开发 C#
在Unity3D中实现热力图、风向图、温度图效果(Unity3D)
因一个任务要完成如何在Unity上面实现热力图的效果,所以百度了很久,发现资料很少,现在就把我总结的如何在Unity上面基于Canvas实现热力图效果的实现过程分享出来, 此前转载了一篇主要讲的是如何根据数据值,在Canvas上重新绘制RGBA的值,完成热力图的绘制,不过用的是H5写的,我修改了一下,用C#重写的
|
9月前
|
存储 数据可视化 关系型数据库
绘制圆环图/雷达图/星形图/极坐标图/径向图POLAR CHART可视化分析汽车性能数据
绘制圆环图/雷达图/星形图/极坐标图/径向图POLAR CHART可视化分析汽车性能数据
MPAndroidChart_RadarChart雷达图的那些事
在最近的使用中,用到了RadarChart,也就是雷达图或者说是蜘蛛图,网上对RadarChart的介绍也并不是很多,所以这里来做一个比较详细的介绍。
316 0
MPAndroidChart_RadarChart雷达图的那些事
用AItium Designer 14 绘制电路图
要使用Altium Designer 14绘制电路图,可以按照以下步骤进行操作: 1. 打开Altium Designer 14软件。 2. 创建一个新的工程:点击“File”(文件)菜单,选择“New”(新建),然后选择“Project”(工程)。在弹出的对话框中,选择一个合适的工程文件夹,并设置工程名称。 3. 在工程中创建一个新的电路图:在左侧的“Projects”(项目)窗格中,展开工程文件夹,右键点击“Schematic”(电路图)文件夹,选择“Add New to Project”(添加新文件到工程)。在弹出的对话框中,选择“Schematic”(电路图),然后设置电路图名称
262 0
【MATLAB】进阶绘图 ( colormap 颜色图矩阵分析 | 自定义 colormap 颜色图 | 生成 64 x 3 的 colormap 颜色图矩阵 )
【MATLAB】进阶绘图 ( colormap 颜色图矩阵分析 | 自定义 colormap 颜色图 | 生成 64 x 3 的 colormap 颜色图矩阵 )
708 0
【MATLAB】进阶绘图 ( colormap 颜色图矩阵分析 | 自定义 colormap 颜色图 | 生成 64 x 3 的 colormap 颜色图矩阵 )
|
传感器
Emgu-WPF 激光雷达研究-绘制雷达图
原文:Emgu-WPF 激光雷达研究-绘制雷达图 硬件:Hokuyo URG04LX 环境:VS2017- win10- 64  Emgu_3.
1070 0
|
C++ Python
C++ VTK鼠标网格表面绘制曲线
C++ VTK鼠标网格表面绘制曲线
519 0
C++ VTK鼠标网格表面绘制曲线

热门文章

最新文章