欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 新闻 > 国际 > QT中使用图表之QChart绘制动态折线图

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

2025/1/3 1:19:25 来源:https://blog.csdn.net/sc_o_r_pio/article/details/143693847  浏览:    关键词:QT中使用图表之QChart绘制动态折线图

使用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); //当前时间+10saxisX -> 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_OBJECTpublic: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); //当前时间+10saxisX -> 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); //当前时间+10saxisX -> 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

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com