QCustomPlot類編寫動態(tài)折線圖,可坐標(biāo)平移
QCustomPlot類編寫動態(tài)折線圖,可坐標(biāo)平移
看本博文前,請先弄清楚QCustomPlot的配置及使用方法,具體請參考網(wǎng)頁:
http://www.myexception.cn/program/1912498.html,本篇博文使用的是第一種方法,也就是提升法。QCustomPlot類的源碼庫下載地址為:
http://download.csdn.net/detail/a2886015/9697439
首先新建Qt APP項(xiàng)目,ui文件使用QWidget,建好后添加qcustomplot.h和qcustomplot.cpp文件到工程里,然后打開ui文件,添加個(gè)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];????//數(shù)據(jù)緩沖數(shù)組
????unsigned?char?CurrentData;
????//實(shí)時(shí)數(shù)據(jù),嵌入式系統(tǒng)中,可將下位機(jī)傳上來的數(shù)據(jù)存于此變量中
????explicit?Widget(QWidget?*parent?=?0);
????~Widget();
???void?ShowLine(QCustomPlot?*customPlot);//顯示折線圖
public?slots:
????void?ReadyShowLine();
????//本例中用于修改實(shí)時(shí)數(shù)據(jù),并調(diào)用ShowLine函數(shù)
private:
????Ui::Widget?*ui;
????unsigned?long?int?flag;
?
?
};
?
#endif?//?WIDGET_H
?
這部分說下為什么需要緩沖區(qū)Buff數(shù)組,以及CurrentData變量。QCustomPlot畫折線圖主要依靠setData()函數(shù),而這個(gè)函數(shù)的原型為:
void?QCPGraph::setData(const QVector
里面的2個(gè)參數(shù)分別是X坐標(biāo)值和Y坐標(biāo)值,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");
????????//初始化坐標(biāo)系范圍和意義
}
?
Widget::~Widget()
{
????delete?ui;
}
?
void?Widget::ShowLine(QCustomPlot?*customPlot)
{
????QVector
????QVector
????//無論如何,折線圖一次能展示的區(qū)域總是有限的,這里一次最多繪制100個(gè)點(diǎn)
????//如果你想圖形更加精細(xì),可以多定義些點(diǎn)
???????if(flag<=99){??//當(dāng)圖形中不足100個(gè)點(diǎn)時(shí),進(jìn)入到if句里處理
???????????Buff[flag]=CurrentData;//將新數(shù)據(jù)存入緩沖區(qū)
???????????for(int?i=0;i<=flag;i++){
???????????????Xvalue[i]=i;
???????????????Yvalue[i]=Buff[i];
??????????????}//分別賦值X軸,Y軸值,產(chǎn)生多少個(gè)實(shí)時(shí)值,就賦值多少個(gè)點(diǎn)
???????????????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;
???????????}
??????//當(dāng)實(shí)時(shí)數(shù)據(jù)超過100個(gè)時(shí),進(jìn)行以下處理
???????for(int?i=0;i<99;i++)
???????{
???????????Buff[i]=Buff[i+1];
???????}
???????Buff[99]=CurrentData;
???????//緩沖區(qū)整體左移,Buff[0]丟棄,Buff[99]接收新數(shù)據(jù)
???????for(int?i=0;i<100;i++)
???????{
???????????Xvalue[i]?=?flag-(99-i);
???????????Yvalue[i]?=Buff[i];
???????}//X,Y軸賦滿100個(gè)值,其中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坐標(biāo)軸跟著平移
???????customPlot->yAxis->setRange(0,100);
???????customPlot->replot();//重繪圖形
???????flag++;
}
?
void?Widget::ReadyShowLine()
{
????CurrentData=CurrentData+5;
????if(CurrentData>=80)?CurrentData=0;//產(chǎn)生鋸齒波,最大值是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張結(jié)果圖:
?
?
?
?