QT中使用图表之QChart绘制动态折线图

news2024/12/23 0:30:24

使用QChart绘制一个随着时间的变化而动态显示的折线图

每一秒增加1个点,总共显示10s内的数据

显然x轴我们使用日期时间轴 

同时使用1个定时器每隔1秒往折线系列中添加1个数据进去

步骤如下:

1、创建图表视图

//1、创建图表视图
QChartView* view=new QChartView(this);

2、创建图表,并将图表设置给视图

//2.创建图表
QChart * chart = new QChart();

//3.将图表设置给图表视图
view -> setChart(chart);

 //设置标题
chart->setTitle("动态折线图");
chart->legend()->show();//显示或者隐藏图例(默认显示)

3、创建x轴(采用QDateTimeAxis日期时间轴),将x轴加到图表中,并设置x的范围为[当前时间,当前时间往后推10s]

//构建x轴-日期时间轴
QDateTimeAxis * axisX = new QDateTimeAxis(this);
axisX -> setTitleText("时间轴");
QDateTime min = QDateTime::currentDateTime(); //当前时间
QDateTime max = min.addSecs(10); //当前时间+10s
axisX -> setRange(min, max); //设置范围,[当前时间,当前时间+10s]
axisX -> setTickCount(11);
axisX -> setFormat("hh:mm:ss"); //设置刻度值的格式
axisX -> setLabelsAngle(45);
chart -> addAxis(axisX, Qt::AlignBottom);

4、创建y轴,将y轴加到图标中

//构建y轴-数值轴
QValueAxis * axisY = new QValueAxis(this);
axisY -> setRange(1000, 2000);
axisY -> setTickCount(11);
axisY -> setTitleText("Y轴");
chart -> addAxis(axisY, Qt::AlignLeft);

5、创建折线系列,并添加到图表中,此时先不往折线系列中添加数据

//构建折线系列
QLineSeries * line = new QLineSeries(this);
line -> setName("时间轴");
chart -> addSeries(line);

6、将x轴和y轴和折线系列进行关联

line -> attachAxis(axisX);
line -> attachAxis(axisY);

7、创建定时器,并开启定时器,在定时器超时信号的槽函数中:

  • 往折线系列中添加数据
  • 并且x值(即当前时间超过了最开始设定的最大值时,更新x轴的范围,新的范围为[当前时间往前推10s,当前时间]
  • 同时删除不可见的点,防止内存一直增长
    //定时器中动态添加数据
    QTimer * t = new QTimer(this);
    t -> setTimerType(Qt::PreciseTimer);
    connect(t, & QTimer::timeout, this, [ = ]() {
    
        auto x = QDateTime::currentMSecsSinceEpoch(); //获取当前时间的毫秒数
        auto y = QRandomGenerator::global() -> bounded(1000, 2000); //y值采用随机数
    
        //第一次触发这个槽函数时更新一下范围,解决开头有几个点没有的bug
        //因为前面设置x轴范围获取的时间和定时器超时的时间点有10ms的间隔,毕竟x轴的精度是毫秒级别
        //这个更新只执行一次
        static std::once_flag once;
        std::call_once(once, [ = ]() {
            QDateTime min_ = QDateTime::fromMSecsSinceEpoch(x); //当前时间
            QDateTime max_ = min_.addSecs(10); //当前时间+10s
            axisX -> setRange(min_, max_); //设置范围,10s的范围
        });
    
        //添加数据
        line -> append(x, y);
    
        QDateTime max = axisX -> max();
    
        //当前x值超过了x轴的最大值
        if (x > max.toMSecsSinceEpoch()) {
            QDateTime new_max = QDateTime::fromMSecsSinceEpoch(x);
            QDateTime new_min = max.addSecs(-10);
    
            //更新最大最小值,范围始终保持10s,更新x轴最大值为新的当前毫秒数
            axisX -> setRange(new_min, new_max);
    
            //删除不可见的点,否则点数越来越多,内存耗尽
            //每次删除第一个点
            line -> removePoints(0, 1);
        }
    });
    
    //开启定时器
    t -> start(10); //10ms增加一个点

    完整代码:

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

#include<QtCharts>

#include<QHBoxLayout>

#include<QPieSlice>

#include<QPieSeries>

#include<QBarSeries>

#include<QBarSet>

#include<QAreaSeries>

class Widget: public QWidget {
    Q_OBJECT

    public:
        Widget(QWidget * parent = nullptr): QWidget(parent) {
            resize(800, 600);
            QHBoxLayout * h_box = new QHBoxLayout(this);
            drawDynamicLineSeries();

        }
        ~Widget() =default;

    //绘制动态折线图
    void drawDynamicLineSeries() {
        //1、创建图表视图
        QChartView * view = new QChartView(this);

        this -> layout() -> addWidget(view);

        //2.创建图表
        QChart * chart = new QChart();

        //3.将图表设置给图表视图
        view -> setChart(chart);

        //设置标题
        chart -> setTitle("动态折线图");
        chart -> legend() -> show(); //显示或者隐藏图例(默认显示)

        //构建x轴-日期时间轴
        QDateTimeAxis * axisX = new QDateTimeAxis(this);
        axisX -> setTitleText("时间轴");
        QDateTime min = QDateTime::currentDateTime(); //当前时间
        QDateTime max = min.addSecs(10); //当前时间+10s
        axisX -> setRange(min, max); //设置范围,[当前时间,当前时间+10s]
        axisX -> setTickCount(11);
        axisX -> setFormat("hh:mm:ss"); //设置刻度值的格式
        axisX -> setLabelsAngle(45);
        chart -> addAxis(axisX, Qt::AlignBottom);

        //构建y轴-数值轴
        QValueAxis * axisY = new QValueAxis(this);
        axisY -> setRange(1000, 2000);
        axisY -> setTickCount(11);
        axisY -> setTitleText("Y轴");
        chart -> addAxis(axisY, Qt::AlignLeft);


        //构建折线系列
        QLineSeries * line = new QLineSeries(this);
        line -> setName("时间轴");
        chart -> addSeries(line);
        line -> attachAxis(axisX);
        line -> attachAxis(axisY);

        //定时器中动态添加数据
        QTimer * t = new QTimer(this);
        t -> setTimerType(Qt::PreciseTimer);
        connect(t, & QTimer::timeout, this, [ = ]() {

            auto x = QDateTime::currentMSecsSinceEpoch(); //获取当前时间的毫秒数
            auto y = QRandomGenerator::global() -> bounded(1000, 2000); //y值采用随机数

            //第一次触发这个槽函数时更新一下范围,解决开头有几个点没有的bug
            //因为前面设置x轴范围获取的时间和定时器超时的时间点有10ms的间隔,毕竟x轴的精度是毫秒级别
            //这个更新只执行一次
            static std::once_flag once;
            std::call_once(once, [ = ]() {
                QDateTime min_ = QDateTime::fromMSecsSinceEpoch(x); //当前时间
                QDateTime max_ = min_.addSecs(10); //当前时间+10s
                axisX -> setRange(min_, max_); //设置范围,10s的范围
            });

            //添加数据
            line -> append(x, y);

            QDateTime max = axisX -> max();

            //当前x值超过了x轴的最大值
            if (x > max.toMSecsSinceEpoch()) {
                QDateTime new_max = QDateTime::fromMSecsSinceEpoch(x);
                QDateTime new_min = max.addSecs(-10);

                //更新最大最小值,范围始终保持10s,更新x轴最大值为新的当前毫秒数
                axisX -> setRange(new_min, new_max);

                //删除不可见的点,否则点数越来越多,内存耗尽
                //每次删除第一个点
                line -> removePoints(0, 1);
            }
        });

        //开启定时器
        t -> start(10); //10ms增加一个点

    }

};
#endif // WIDGET_H

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2238672.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

自然语言处理在客户服务中的应用

&#x1f493; 博客主页&#xff1a;瑕疵的CSDN主页 &#x1f4dd; Gitee主页&#xff1a;瑕疵的gitee主页 ⏩ 文章专栏&#xff1a;《热点资讯》 自然语言处理在客户服务中的应用 自然语言处理在客户服务中的应用 自然语言处理在客户服务中的应用 引言 自然语言处理概述 定义…

vs2022搭建opencv开发环境

1 下载OpenCV库 https://opencv.org/ 下载对应版本然后进行安装 将bin目录添加到系统环境变量opencv\build\x64\vc16\bin 复制该路径 打开高级设置添加环境变量 vs2022新建一个空项目 修改属性添加头文件路径和库路径 修改链接器&#xff0c;将OpenCV中lib库里的o…

【含文档】基于ssm+jsp的校园疫情管理系统(含源码+数据库+lw)

1.开发环境 开发系统:Windows10/11 架构模式:MVC/前后端分离 JDK版本: Java JDK1.8 开发工具:IDEA 数据库版本: mysql5.7或8.0 数据库可视化工具: navicat 服务器: apache tomcat 主要技术: Java,Spring,SpringMvc,mybatis,mysql,vue 2.视频演示地址 3.功能 系统定义了两个…

在Django中安装、配置、使用CKEditor5,并将CKEditor5录入的文章展现出来,实现一个简单博客网站的功能

在Django中可以使用CKEditor4和CKEditor5两个版本&#xff0c;分别对应软件包django-ckeditor和django-ckeditor-5。原来使用的是CKEditor4&#xff0c;python manager.py makemigrations时总是提示CKEditor4有安全风险&#xff0c;建议升级到CKEditor5。故卸载了CKEditor4&…

网络管理之---3种网络模式配置

目标&#xff1a; 了解几个概念&#xff1a; 1.什么是IP&#xff1f;什么是IP地址&#xff1f; 2.什么是桥接、NAT、仅主机模式 3.端口&#xff1f; 4.什么是网络接口命名规则 5.网络管理器 IP&#xff1a;指网络之间互联的协议&#xff0c;是TCP/IP 体系中的网络协议 I…

统信UOS开发环境支持Electron

全面支持Electron开发环境,同时还提供了丰富的开发工具和开发资源,进一步提升工作效率。 文章目录 一、环境部署1. Electron应用开发介绍2. Electron开发环境安装安装Node.js和npm安装electron环境配置二、代码示例Electron开发案例三、常见问题一、环境部署 1. Electron应用…

三级等保安全解决方案,实施方案,整改方案(Word,PPT等相关资料学习)

信息系统进行三级等保的主要原因在于保障信息安全&#xff0c;维护国家安全和公共利益。三级等保是我国根据相关法律法规制定的信息安全等级保护制度中的一部分&#xff0c;旨在确保信息系统的完整性、可用性和保密性。通过三级等保&#xff0c;信息系统可以得到一系列的安全保…

优选算法合集————双指针(专题一)

题目一&#xff1a;移动零 题目描述&#xff1a; 给定一个数组 nums&#xff0c;编写一个函数将所有 0 移动到数组的末尾&#xff0c;同时保持非零元素的相对顺序。 请注意 &#xff0c;必须在不复制数组的情况下原地对数组进行操作。 示例 1: 输入: nums [0,1,0,3,12] 输…

python基于深度学习的音乐推荐方法研究系统

需求设计 一款好的音乐推荐系统其目的是为用户进行合理的音乐推荐&#xff0c;普通的用户在登录到系统之后&#xff0c;能够通过搜索的方式获取与输入内容相关的音乐推荐&#xff0c;而以管理员登录到系统之后&#xff0c;则可以进行徐昂管的数据管理等内容操作。此次的需求主…

Docker 镜像和容器的导入导出及常用命令

Docker 镜像和容器的导入导出 1.1 镜像的导入导出 1.1.1 镜像的保存 通过镜像ID保存 方式一&#xff1a; docker save image_id > image-save.tar例如&#xff1a; rootUbuntu:/usr/local/docker/nginx# docker imagesREPOSITORY TAG IMAGE ID …

Java集合 List——针对实习面试

目录 Java集合 ListJava List的三种主要实现是什么&#xff1f;它们各自的特点是什么&#xff1f;Java List和Array&#xff08;数组&#xff09;的区别&#xff1f;Java List和Set有什么区别&#xff1f;ArrayList和Vector有什么区别&#xff1f;什么是LinkedList&#xff1f;…

超级干货O2OA数据中心-查询配置开发

O2OA提供的数据管理中心&#xff0c;可以让用户通过配置的形式完成对数据的汇总&#xff0c;统计和数据分组展现&#xff0c;查询和搜索数据形成列表数据展现。也支持用户配置独立的数据表来适应特殊的业务的数据存储需求。本文主要介绍如何在O2OA中开发和配置自定义数据查询语…

Unity中IK动画与布偶死亡动画切换的实现

在Unity游戏开发中&#xff0c;Inverse Kinematics&#xff08;IK&#xff09;是创建逼真角色动画的强大工具。同时&#xff0c;能够在适当的时候切换到布偶物理状态来实现死亡动画等效果&#xff0c;可以极大地增强游戏的视觉体验。本文将详细介绍如何在Unity中利用IK实现常规…

【ArcGISPro】单次将自己建立的工具箱添加至Arcpy中

新建工具箱 添加至Arcpy中 调用刚添加的工具箱

JVM的组成、字节码文件的组成

目录 java虚拟机的组成 字节码文件的组成 基础信息 常量池 字段 方法 属性 字节码相关的常用工具&#xff1a; 总结&#xff1a; 1、如何查看字节码文件&#xff1f; 2、字节码文件的核心组成有哪些&#xff1f; java虚拟机的组成 类加载器 ClassLoader运行时数据区…

新的服务器Centos7.6 安卓基础的环境配置(新服务器可直接粘贴使用配置)

常见的基础服务器配置之Centos命令 正常来说都是安装一个docker基本上很多问题都可以解决了&#xff0c;我基本上都是通过docker去管理一些容器如&#xff1a;mysql、redis、mongoDB等之类的镜像&#xff0c;还有一些中间件如kafka。下面就安装一个 docker 和 nginx 的相关配置…

Mysql COUNT() 函数详解

Mysql COUNT 函数详解 COUNT() 的几种用法COUNT(*)COUNT(1)COUNT(column)COUNT(*) 与 GROUP BYCOUNT(*) 与 GROUP BY 和 HAVING COUNT(expr) 的用法COUNT(DISTINCT expr)COUNT(expr) 带条件查询 写在最后 在使用Mysql的时候&#xff0c;作为开发者&#xff0c;聚合函数是肯定会…

yum下载时出现报错 Couldn‘t read a file:// file for file:///mnt/repodata/repomd.xml

得知说yum源指定的/mnt/没有镜像源 发现可能是镜像没有挂载成功 mount /dev/cdrom /mnt 清理一下缓存重新试一下 yum clean all yum install mod_ssl 解决

视觉SLAM数学基础

本文系统梳理从相机成像模型&#xff0c;通过不同图像帧之间的构造几何约束求解位姿变换&#xff0c;再根据位姿变换和匹配点还原三维坐标的过程&#xff0c;可以作为基于特征点法的视觉SLAM的数学基础。 1、相机成像模型 1.1、针孔相机模型 实际相机的成像方式通常很复杂&a…

书生大模型第四期闯关任务与笔记

书生大模型第四期闯关任务与笔记 入门岛第一关 Linux闯关任务&#xff1a;完成SSH连接与端口映射并运行hello_world.py笔记与过程SSH端口映射linux文件管理命令linux进程管理命令 第二关 Python闯关任务&#xff1a;Leetcode 383(笔记中提交代码与leetcode提交通过截图)闯关任务…