#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <qwt_plot_item.h>
#include <qwt_plot_dict.h>
//版本1.1
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
setupRealtimeDataDemo(ui->qwtPlot);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::setupRealtimeDataDemo(QwtPlot *qwtplot)
{
//初始化xdata,x对应长度为5的坐标,y初始全为0
for(int i=1;i<5001;i++)//计算曲线数据
{
xdata.append(double(i)/1000-5);//xdata添加元素
xdata2=xdata;
ydata.append(0);
ydata2=ydata;
}
demoName = "实时数据演示";
qwtplot->setTitle(demoName);//设置标题
qwtplot->setCanvasBackground(Qt::gray);//背景灰色
// qwtplot->insertLegend(legend1,QwtPlot::RightLegend);//添加图例(标注)
curve = new QwtPlotCurve();//new一个曲线
curve->setTitle("肌电信号");//曲线名字
curve->setPen( Qt::yellow, 1 );//曲线的颜色黄色 宽度1;
// curve->setLegendAttribute(curve->LegendShowLine);//指定一个属性如何绘制图例图标,显示图例的标志,这里显示线的颜色。
curve2 = new QwtPlotCurve();//new一个曲线
curve2->setTitle("另一个信号");//曲线名字
curve2->setPen( Qt::green, 1 );//曲线的颜色黄色 宽度1;
QTime curtime;
curtime=curtime.currentTime();
qwtplot->setAxisTitle(QwtPlot::xBottom, " 系统运行时间");//设置轴标题
qwtplot->setAxisTitle(QwtPlot::yLeft,"肌电图");//设置轴标题
qwtplot->setAxisScale(QwtPlot::yLeft,-2,2,0);//禁用自动缩放比例尺,为某个坐标轴指定一个修改的比例尺
qwtplot->setAxisScale(QwtPlot::xBottom,-5,0,0);//禁用自动缩放比例尺,为某个坐标轴指定一个修改的比例尺
QwtPlotZoomer *zoomer = new QwtPlotZoomer( qwtplot->canvas() );//可变焦距镜头
zoomer->setRubberBandPen( QColor( Qt::blue ) );
zoomer->setTrackerPen( QColor( Qt::black ) );
zoomer->setMousePattern(QwtEventPattern::MouseSelect2,Qt::RightButton, Qt::ControlModifier );
zoomer->setMousePattern(QwtEventPattern::MouseSelect3,Qt::RightButton );
QwtPlotMagnifier *magnifier = new QwtPlotMagnifier( qwtplot->canvas() );//使用滚轮放大/缩小 //默认的滑轮及右键缩放功能 图形的整体缩放
//magnifier->setMouseButton(Qt::LeftButton); //设置哪个按钮与滑轮为缩放画布 如果不设置(注册掉当前行)按钮默认为滑轮以及右键为缩放
QwtPlotGrid *grid = new QwtPlotGrid();//new网格线
grid->enableX( true );//设置X网格线
grid->enableY( true );
grid->setMajorPen( Qt::black, 0, Qt::DotLine );//设置网格线性和颜色
grid->attach(qwtplot);//把曲线附加到QwlPlot上
connect(&updateTimer,SIGNAL(timeout()),this,SLOT(updatedataSlot()));//信号和槽
updateTimer.start(0);//设置刷新时间
QwtLegend *legend = new QwtLegend;
legend->setDefaultItemMode( QwtLegendData::Checkable );//图例可被点击
qwtplot->insertLegend( legend, QwtPlot::RightLegend );//图例位置设计
connect( legend, &QwtLegend::checked,this,&MainWindow::showItem);//点击图例显示曲线
ui->qwtPlot->replot();
}
void MainWindow::showItem( const QVariant &itemInfo, bool on )//显示曲线
{
QwtPlotItem *plotItem =ui->qwtPlot->infoToItem( itemInfo );
if ( plotItem )
plotItem->setVisible( on );
}
/**
* @brief getData
* @param inteval
* @return
* 获取一个值 模拟串口接收到的值
*/
double MainWindow::getData(double time){
double s = qSin( time * M_PI * 2 ) ;
return s;
}
//用于更新ydata,实际情况就是read数据,关于刷新数据,建议大家看这个http://tedeum.iteye.com/blog/2018706
//这份代码刷新的曲线数据我没看懂,我用的是两个数组分别存储每个点的X,Y坐标
void MainWindow::updatedataSlot()
{
static QTime dataTime(QTime::currentTime());
long int eltime = dataTime.elapsed();
static int lastpointtime = 0;
int size = (eltime - lastpointtime);
if(size>0){//有数据传入
ydata.erase(ydata.begin(),ydata.begin()+size);//擦除多余的数据
ydata2.erase(ydata2.begin(),ydata2.begin()+size);//擦除多余的数据
for(int i=1;i<size+1;i++){
ydata.append(getData((((double)lastpointtime+i)/1000)));//这参数没搞懂 不过我在写工程时实际刷新的数据是真实的数据
ydata2.append((-1)*getData((((double)lastpointtime+i)/1000)));
}
lastpointtime = eltime;
}
curve->setSamples(xdata,ydata);//设置曲线数据
curve2->setSamples(xdata2,ydata2);
curve->attach(ui->qwtPlot);//把曲线附加到QwlPlot上
curve2->attach(ui->qwtPlot);
ui->qwtPlot->replot();//刷新qwt
}