1. Qt画图太难了呀😭
Qt虽属于图形用户界面应用程序开发框架,但是不提供例如matlab以及python的plot接口,这使得Qt的绘图显得比较繁琐,但是没有集成化的接口使用,Qt也提供了画图的对象,相比于plot库,我们需要实例化一个画图对象,配置坐标轴、绑定数据以及将图表加入窗口显示。虽说较为繁琐,但是灵活性也更高☀️ 。
首先,我们先放出基于本博文做出来的图表效果:自行判断本博文有没有参考价值📝
2. QtCharts图表组件📈
过去听说我也没用过🏃 ,Qt官方并没有提供画图的库需要安装第三方的qcustomplot功能不全和qwt安装麻烦插件,自从Qt5推出后,官方就集成了QtCharts,但是需要我们在安装选项中进行勾选,也可以使用MaintenanceTool进行后续安装我试了,没成功,项目比较赶,就选择了重装,太菜了🎍 !有方法的大佬记得文末评论,互相学习
3. QtCharts画二维曲线图步骤
参看如下步骤,只说大致,细节添加头文件、定义数据成员等需要参考源代码:
3.1 修改.pro文件
值得注意的是,QtCharts并不是Qt的默认核心组件,使用QtCharts我们需要修改.pro工程文件,添加引用QtCharts的脚本。
QT += core gui
# 添加如下脚本
QT +=charts
3.2 使用命名空间
QtCharts相关的数据结构仅仅通过引入头文件是不够的,比如使用QChart定义数据成员,就算添加了头文件也会发信啊报如下错误:
unknown type name 'QChart'
错误的原因主要是没有使用相对应的命名空间,这时候有些同学就要扛了,我使用全称不久行了嘛?当然也可以!但是使用命名空间会显得代码没那么臃肿。在头文件中加入如下“宏”[1]
QT_CHARTS_USE_NAMESPACE
[1] 不知道导入命名空间的语句属于啥?😕
3.3 初始化QChart
QChart属于图表本身,QChartView是图表展示的载体 (编不下去了,我也不懂为啥要这样分,使用得不深,有待研究)。
初始化QChart主要做如下几个配置,注意:不是必须的,你默认也可能🏃♀ 没啥问题。
- 绑定数据:实例化数据对象、往数据集合添加数据、使用addSeries()绑定数据;
- 设置XY坐标轴:这里有多种方式,可以实例化一个轴对象、也可以设置默认坐标轴。具体看代码吧。。。
splineSeries = new QSplineSeries();
QPen pen(0x000001);
pen.setWidth(1);
splineSeries->setPen(pen); //设置画笔颜色和大小
scatterSeries = new QScatterSeries();
scatterSeries->setMarkerSize(5); //设置散点大小
scatterSeries->setColor(0x0000FF); //设置散点颜色
chart = new QChart();
chart->addSeries(splineSeries); //添加数据源
chart->addSeries(scatterSeries); //添加数据源
chart->legend()->hide(); //关闭图例
chart->setTitle("实时动态曲线");
chart->createDefaultAxes();
//设置X轴,此类方式已经被弃用(不推荐,会报警告,但可读性更高)
// chart->axisX()->setRange(0, maxX);
// chart->axisX()->setGridLineVisible(false);
// chart->axisX()->setTitleText("X轴");
//设置Y轴
// chart->axisY()->setRange(0, maxY);
// chart->axisY()->setGridLineVisible(false);
// chart->axisY()->setTitleText("Y轴");
//上述方式已经被下面这种方式代替(推荐,不会报警告,但可读性不高)
chart->axes(Qt::Horizontal).back()->setRange(0, maxX);
chart->axes(Qt::Horizontal).back()->setGridLineVisible(false);
chart->axes(Qt::Horizontal).back()->setTitleText("X轴");
chart->axes(Qt::Vertical).back()->setRange(0, maxY);
chart->axes(Qt::Vertical).back()->setGridLineVisible(false);
chart->axes(Qt::Vertical).back()->setTitleText("Y轴");
第一种方式设置轴会报出警告,当然如下警告问题不大,但是不适合长期使用。
warning:'axisX' is deprecated. //该功能被弃用了,虽说被弃用,只是说官方不推荐,还可以用
3.4 初始化QChartView
最基本的QChartView初始化非常简单,只需要利用已初始化的QChart实例化一个QChartView即可:
//为chart对象实例化一个Qchartview
chartView = new QChartView(chart);
3.5 将QChartView加入窗口
QChartView并不是Qt的基本控件,需要依赖于基本空间显示,我们使用的是MainWindow窗口中自带的widget显示我们的图表:
QHBoxLayout *layout = new QHBoxLayout();
layout->addWidget(chartView);
ui->centralWidget->setLayout(layout);
至此,我们的图表就可以展示出来啦,但是我的代码还没有往数据集合中添加数据,所以不会出现数据曲线,大家注意!
4. 模拟滚动动画
所谓的滚动动画,其实就是删除头数据,整体数据前移一个单位,尾插入最新的数据。我们可以使用删除操作更方便的链表进行数据存储。由于QChart之前已经绑定了数据集合,此时我们修改图表数据只需要修改对应的数据集合即可,无须进行刷新页面操作。为了更好的演示滚动动画,我们引用了定时器,设定定时器200ms即发出信号,调用对应的槽函数。
启动定时器:
//初始化定时器,100ms定时一次
timerId = startTimer(300);
槽函数:
void MainWindow::timerEvent(QTimerEvent *event)
{
// 产生一个数据,模拟不停的接收到新数据
int newData;
if (event->timerId() == timerId) {
newData = qrand() % maxY;
data << newData;
// 数据个数超过了最大数量,删除首个,数据往前移,添加最后一个
if (data.size() > maxSize) {
data.pop_front();
}
//清空数据
splineSeries->clear();
scatterSeries->clear();
//以1为步长
for (int i = 0; i < data.size(); ++i) {
splineSeries->append(i, data.at(i));
scatterSeries->append(i, data.at(i));
}
}
}
5.源代码
提取码:urz0