QCustomPlot类编写动态折线图,可坐标平移
扫描二维码
随时随地手机看文章
QCustomPlot类编写动态折线图,可坐标平移
看本博文前,请先弄清楚QCustomPlot的配置及使用方法,具体请参考网页:
http://www.myexception.cn/program/1912498.html,本篇博文使用的是第一种方法,也就是提升法。QCustomPlot类的源码库下载地址为:
http://download.csdn.net/detail/a2886015/9697439
首先新建Qt APP项目,ui文件使用QWidget,建好后添加qcustomplot.h和qcustomplot.cpp文件到工程里,然后打开ui文件,添加个widget部件到界面上,采用栅格布局,最后将widget部件提升为QCustomPlot类。这些都是QCustomPlot类的配置部分,就不多说了。
在widget.h文件里写入如下代码:
#ifndef WIDGET_H
#define WIDGET_H
#include
#include "qcustomplot.h"
#include
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
double Buff[100]; //数据缓冲数组
unsigned char CurrentData;
//实时数据,嵌入式系统中,可将下位机传上来的数据存于此变量中
explicit Widget(QWidget *parent = 0);
~Widget();
void ShowLine(QCustomPlot *customPlot);//显示折线图
public slots:
void ReadyShowLine();
//本例中用于修改实时数据,并调用ShowLine函数
private:
Ui::Widget *ui;
unsigned long int flag;
};
#endif // WIDGET_H
这部分说下为什么需要缓冲区Buff数组,以及CurrentData变量。QCustomPlot画折线图主要依靠setData()函数,而这个函数的原型为:
void QCPGraph::setData(const QVector
里面的2个参数分别是X坐标值和Y坐标值,QVector
接下来是widget.cpp文件里的代码:
#include "widget.h"
#include "ui_widget.h"
#include
#include
QVector
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
for(int i=0;i<100;i++)
{
Buff[i] = 0;
}
CurrentData=0;
flag=0;
QTimer *timer = new QTimer(this);
timer->start(200);//每200ms重绘一次折线图
connect(timer,SIGNAL(timeout()),this,SLOT(ReadyShowLine()));
ui->widget->xAxis->setRange(0,100);
ui->widget->yAxis->setRange(0,100);
ui->widget->xAxis->setLabel("time");
ui->widget->yAxis->setLabel("data");
//初始化坐标系范围和意义
}
Widget::~Widget()
{
delete ui;
}
void Widget::ShowLine(QCustomPlot *customPlot)
{
QVector
QVector
//无论如何,折线图一次能展示的区域总是有限的,这里一次最多绘制100个点
//如果你想图形更加精细,可以多定义些点
if(flag<=99){ //当图形中不足100个点时,进入到if句里处理
Buff[flag]=CurrentData;//将新数据存入缓冲区
for(int i=0;i<=flag;i++){
Xvalue[i]=i;
Yvalue[i]=Buff[i];
}//分别赋值X轴,Y轴值,产生多少个实时值,就赋值多少个点
flag++;
customPlot->addGraph();
customPlot->graph(0)->setPen(QPen(Qt::red));
customPlot->graph(0)->setData(Xvalue,Yvalue);
customPlot->xAxis->setLabel("time");
customPlot->yAxis->setLabel("data");
customPlot->xAxis->setRange(0,100);
customPlot->yAxis->setRange(0,100);
customPlot->replot();//重绘图形
return;
}
//当实时数据超过100个时,进行以下处理
for(int i=0;i<99;i++)
{
Buff[i]=Buff[i+1];
}
Buff[99]=CurrentData;
//缓冲区整体左移,Buff[0]丢弃,Buff[99]接收新数据
for(int i=0;i<100;i++)
{
Xvalue[i] = flag-(99-i);
Yvalue[i] =Buff[i];
}//X,Y轴赋满100个值,其中X轴要跟着增加
customPlot->addGraph();
customPlot->graph(0)->setPen(QPen(Qt::red));
customPlot->graph(0)->setData(Xvalue,Yvalue);
customPlot->xAxis->setLabel("time");
customPlot->yAxis->setLabel("data");
customPlot->xAxis->setRange(0+flag-99,100+flag-99);
//X坐标轴跟着平移
customPlot->yAxis->setRange(0,100);
customPlot->replot();//重绘图形
flag++;
}
void Widget::ReadyShowLine()
{
CurrentData=CurrentData+5;
if(CurrentData>=80) CurrentData=0;//产生锯齿波,最大值是75
ShowLine(ui->widget);
}
这部分的解释代码里都写上了,就不多说了,最后是main.cpp里的代码,保持不变就可以了:
#include "widget.h"
#include
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
最后给出4张结果图: