Qt | 利用QtChart实现动态曲线实时绘制显示
前言
QtCharts是Qt提供的图表模块,在Qt5.7以前只有商业版才有QtCharts,但是从5.7开始,社区版也包含了QtCharts。QtCharts可以很方便地绘制常见的折线图、柱状图、饼图等图表。
本章节示例代码下载:https://gitee.com/jhuangBTT/QtDynamicCurveGraphDemo
相关类介绍
1、QChart
用于管理图表中的线、图例和轴的图形表示。可以简单理解为是一个画布。
2、QChartView
视图组件,无法单独进行显示,需要依附其他组件进行显示,如在窗口设计界面先放置一个QGraphicsView组件,然后升级为QChartView;随后QChartView通过setChart将QChart添加为显示的图表。
3、QLineSeries
行序列,数据的表现形式,也就是我们要显示的数据,例如折线图。一般是通过QChart的addSeries将QLineSeries添加到图表中,当然不止QLineSeries,还有其他很多类型。
4、QValueAxis
坐标轴。具体使用步骤为:①使用QChart的addAxis将坐标轴添加到图表上;②使用QLineSeries的attachAxis设置数据与坐标轴的关系;注意这两步设置有先后关系,必须先将坐标轴添加到QChart,如果顺序反了会提示没有与之关联的坐标轴。
总结:以上类明白后,那么我们写程序的步骤也就明确了。需要创建一个图表QChart、横纵坐标轴QValueAxis、数据序列QLineSeries;然后使用QChart->addAxis方法将刚创建的坐标轴添加上;接着使用数据序列QLineSeries->attachAxis与坐标轴关联起来;最后将图表QChart设置到QGraphicsView上进行显示就完成了。数据更新就是使用QLineSeries的append函数即可。
开始Coding
注意:
- 要想使用QChart,需要在安装Qt的时候勾选QChart,否则无法使用
- 在
.pro
文件中引入QChart模块:QT += core gui charts
- 光添加头文件QChartView还不够,还需要引入QChart的命名空间,使用宏
QT_CHARTS_USE_NAMESPACE
本次例程创建了10X10的坐标轴,使用一个周期为200ms的定时器来模拟数据刷新,实现动态曲线模拟模拟真实数据刷新显示。
先添加一个QGraphicsView并将其提升为QChartView:
有了上面的总结后,代码编写就比较容易了,示例程序如下:
//
// 创建横纵坐标轴并设置显示范围
//
m_axisX = new QValueAxis();
m_axisY = new QValueAxis();
m_axisX->setTitleText("X-label");
m_axisY->setTitleText("Y-label");
m_axisX->setMin(0);
m_axisY->setMax(0);
m_axisX->setMax(AXIS_MAX_X);
m_axisY->setMax(AXIS_MAX_Y);
m_lineSeries = new QLineSeries(); // 创建曲线绘制对象
m_lineSeries->setPointsVisible(true); // 设置数据点可见
m_lineSeries->setName("随机数曲线"); // 图例名称
m_chart = new QChart(); // 创建图表对象
m_chart->addAxis(m_axisX, Qt::AlignLeft); // 将X轴添加到图表上
m_chart->addAxis(m_axisY, Qt::AlignBottom); // 将Y轴添加到图表上
m_chart->addSeries(m_lineSeries); // 将曲线对象添加到图表上
m_chart->setAnimationOptions(QChart::SeriesAnimations); // 动画:能使曲线绘制显示的更平滑,过渡效果更好看
m_lineSeries->attachAxis(m_axisX); // 曲线对象关联上X轴,此步骤必须在m_chart->addSeries之后
m_lineSeries->attachAxis(m_axisY); // 曲线对象关联上Y轴,此步骤必须在m_chart->addSeries之后
ui->graphicsView->setChart(m_chart); // 将图表对象设置到graphicsView上进行显示
ui->graphicsView->setRenderHint(QPainter::Antialiasing); // 设置渲染:抗锯齿,如果不设置那么曲线就显得不平滑
周期为200ms的定时器回调函数里面进行数据更新:
void Widget::slotTimeout()
{
int count = m_lineSeries->points().size(); // 获得当前数据序列点数
if(count > AXIS_MAX_X)
{
m_chart->axisX()->setMax(count); // 更新X轴范围
}
m_lineSeries->append(QPointF(count, rand() % AXIS_MAX_Y)); // 更新显示(随机生成10以内的一个数)
}
显示效果如下:
如果不想累加显示,只显示固定N个点数,那么就是来新数据后移除第一个,将新数据添加到最后,代码这样:
void Widget::slotTimeout()
{
static int count = 0;
if(count > AXIS_MAX_X)
{
m_lineSeries->remove(0);
m_chart->axisX()->setMin(count - AXIS_MAX_X);
m_chart->axisX()->setMax(count); // 更新X轴范围
}
m_lineSeries->append(QPointF(count, rand() % AXIS_MAX_Y)); // 更新显示(随机生成10以内的一个数)
count++;
}
显示效果:
ends…