1.前言
本文使用Qchart进行了一个折线图的实现,其功能特点表现为:
1.X轴左端不动,数据不断迭代——可观察总体趋势(文中还会给出左端隧动的改动,实现两种需要)
2.本程序是从一个我做的演示程序中单独摘除出来的三折线图,所以三条线都简单用随机数生成指代数据——若需要真正的多通道折线图,可以自行学习再做升级。本文仅提供思路,演示折线图的基本功能。
3.能够将每一条折线的实时数据呈现在文本框上——此处利用了上篇串口助手的文本呈现方式,将年月日时分秒修改为了时分秒,方便记录数据产生时间。
4.效果图以及视频如下:
QChart多线折线图演示视频
2.代码
1.首先是.pro中引用:
QT += charts
2.其次是.h文件的代码:
#ifndef LAST_H
#define LAST_H
#include <QWidget>
//折线图
#include <QtCharts>
#include <QTimer>
#include <QChartView>
#include <QValueAxis>
#include <QLineSeries>
以下两个均在.h文件的class内:
private slots:
//折线图
void slotTimeout();
void on_clear_clicked(bool checked);
void on_starttime_clicked(bool checked);
private:
Ui::Last *ui;
//折线图板块
/* 用于模拟生成实时数据的定时器 */
QTimer* m_timer;
/* 图表对象 */
QChart* m_chart;
/* 横纵坐标轴对象 */
QValueAxis *m_axisX, *m_axisY;
/* 曲线图对象 */
QLineSeries* m_lineSeriesCa;
QLineSeries* m_lineSeriesK;
QLineSeries* m_lineSeriesNa;
/* 横纵坐标最大显示范围 */
const int AXIS_MAX_Y = 50, AXIS_MAX_X = 10;
/* 用来记录数据点数 */
int pointCount =0;//代表从零开始画曲线,后续的判定由if语句实现。
int K;//转换字符类型用的、标记。
int Ca;
int Na;
3.其次是.cpp文件
#include "last.h"
#include "ui_last.h"
Last::Last(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Last)
{
ui->setupUi(this);
//折线图
m_timer = new QTimer(this);
m_timer->setSingleShot(false);
QObject::connect(m_timer, SIGNAL(timeout()), this, SLOT(slotTimeout()));
QObject::connect(ui->clear, SIGNAL(clicked(bool)), this, SLOT(on_clear_clicked()));
QObject::connect(ui->starttime, SIGNAL(clicked(bool)), this, SLOT(on_starttime_clicked()));
// 创建横纵坐标轴并设置显示范围
m_axisX = new QValueAxis();
m_axisY = new QValueAxis();
m_axisX->setTitleText("X");
m_axisY->setTitleText("Y");
m_axisX->setMin(0);
m_axisY->setMin(0);
m_axisX->setMax(AXIS_MAX_X);
m_axisY->setMax(AXIS_MAX_Y);
m_axisX->setTickCount(5+1);//加1是为了凑整,“1”是0的代指,可以自行修改不加1后带来的变化。
m_axisY->setTickCount(5+1);//这两个是设置网格数量
m_axisX->setGridLineVisible(false);//隐藏网格线
m_axisY->setGridLineVisible(false);
m_lineSeriesNa =new QLineSeries();
m_lineSeriesK =new QLineSeries();
m_lineSeriesCa = new QLineSeries(); // 创建曲线绘制对象
m_lineSeriesNa->setPointsVisible(false);
m_lineSeriesK->setPointsVisible(false);
m_lineSeriesCa->setPointsVisible(false); // 设置数据点可见
m_lineSeriesNa->setName("Na");
m_lineSeriesK->setName("K");
m_lineSeriesCa->setName("Ca"); // 图例名称
m_chart = new QChart(); // 创建图表对象
m_chart->addAxis(m_axisX, Qt::AlignBottom); // 将X轴添加到图表上
m_chart->addAxis(m_axisY, Qt::AlignLeft); // 将Y轴添加到图表上
m_chart->addSeries(m_lineSeriesCa); // 将曲线对象添加到图表上
m_chart->addSeries(m_lineSeriesK);
m_chart->addSeries(m_lineSeriesNa);
m_chart->setAnimationOptions(QChart::SeriesAnimations); // 动画:能使曲线绘制显示的更平滑,过渡效果更好看
m_lineSeriesCa->attachAxis(m_axisX); // 曲线对象关联上X轴,此步骤必须在m_chart->addSeries之后
m_lineSeriesK->attachAxis(m_axisX);
m_lineSeriesNa->attachAxis(m_axisX);
m_lineSeriesCa->attachAxis(m_axisY); // 曲线对象关联上Y轴,此步骤必须在m_chart->addSeries之后
m_lineSeriesK->attachAxis(m_axisY);
m_lineSeriesNa->attachAxis(m_axisY);
ui->graphicsView->setChart(m_chart); // 将图表对象设置到graphicsView上进行显示
ui->graphicsView->setRenderHint(QPainter::Antialiasing);
}
void Last::slotTimeout()
{
QString sysTime;//定义系统时间变量
int pointcount = m_lineSeriesCa->points().size();//随时获得当前序列的点数,用作后面X轴一直递增
if(pointCount > AXIS_MAX_X)
{
// m_chart->axisX()->setMin(pointCount - AXIS_MAX_X);//此段是左X轴值随动。取消注释即可使X左端随动。
m_chart->axisX()->setMax(pointCount); // 更新X轴范围
}
int Na =rand() % AXIS_MAX_Y;
int Ca =rand() % AXIS_MAX_Y;
int K =rand() % AXIS_MAX_Y;
QString na = QString::number(Na);//int转化为string给后面的文本框显示
QString ca = QString::number(Ca);//int转化为string
QString k = QString::number(K);//int转化为string
m_lineSeriesCa->append(QPointF(pointCount, Ca)); // 更新显示(随机生成最大Y轴坐标以内的一个数)
m_lineSeriesK->append(QPointF(pointCount, K));
m_lineSeriesNa->append(QPointF(pointCount, Na));// 这是点的描述:QPointF(pointCount, rand() % AXIS_MAX_Y)
sysTime = QDateTime::currentDateTime().toString("hh:mm:ss\n");//换行使用\n即可
ui->Na->append(sysTime+QString("结果:"+na));//文本显示格式
ui->Ca->append(sysTime+QString("结果:"+ca));
ui->K->append(sysTime+QString("结果:"+k));
pointCount++;
}
Last::~Last()
{
delete ui;
}
void Last::on_clear_clicked(bool checked)
{
m_lineSeriesCa->clear();
m_lineSeriesK->clear();
m_lineSeriesNa->clear();
m_chart->axisX()->setMin(0);
m_chart->axisX()->setMax(AXIS_MAX_X);
pointCount = 0;
}
void Last::on_starttime_clicked(bool checked)//bool开关的作用是一直保持着上一个状态
{
if(m_timer->isActive())
{
m_timer->stop();
// ui->starttime->setText("启动定时器");//提示按个人需要可加可不加
}else
{
m_timer->start(200);//更改括号内数值可改变随机数出现速度,计时
// ui->starttime->setText("停止定时器");
//pointCount = 0;//此语句将会导致每次暂停后再开启会从零开始。
}
}
3.ui文件需要的控件
1.QGraphics View:1个——作为折线图铺开的基底。
需要的操作:将其拖拽出来之后。右键点击提升为>跳转到新窗口之后点击“提升的类名称”里,输入“QChartView”>点击添加即可。
2.QPushButton:2个——作为开始/暂停以及清除按钮。
2个都需要的操作:右键按钮>转到槽>点击“clicked(bool)”
即可编辑槽函数内容。
3.QTextBrowser:3个——作为三条曲线的数据显示。
这个根据需要随意设置。
4.最后
此程序能够改变的有很多,也通俗易懂,多看几遍代码,理清楚各个部分之间的关系,很快就能自己修改出适合自己需求的折线图程序。当然,更高级的视图类程序也在等着大家,学无止境,一直向前。