关于Qwt绘制动态折线的尝试
设备:Mac Qt版本:5.12.9
1、首先建立一个带界面的Qt工程, 然后在工程文件中加入以下一行(括号里换成自己的qwt路径):
include(/Users/xjk/Downloads/qwt-6.1.5/qwt.prf)
2、右击项目,AddNew,添加C++类,基类选QWidgt,然后继承自QwtPlot类,方便以后使用。
头文件代码如下:
#ifndef MYPLOT_H #define MYPLOT_H #include <QWidget> #include <QVector> #include <QPointF> #include <qwt_plot.h> #include <qwt_plot_canvas.h> #include <qwt_plot_curve.h> #include <qwt_plot_grid.h> #include <qwt_plot_zoomer.h> class MyPlot : public QwtPlot { Q_OBJECT public: explicit MyPlot(QWidget *parent = nullptr); ~MyPlot(); public slots: void slotDrawLine(QVector<double>); private: QVector<double> xData; QwtPlotCurve *curve1; void clear(); }; #endif // MYPLOT_H
源码如下:
#include "myplot.h" MyPlot::MyPlot(QWidget *parent) : QwtPlot(parent) { //初始化横坐标 xData.clear(); for (int i=0;i<100;++i) { xData.push_back(i); } setAutoFillBackground( true ); //设置坐标轴 setAxisTitle( xBottom, "x -->" ); setAxisScale( xBottom, 0.0, 100.0,10 ); setAxisTitle( yLeft, "y -->" ); setAxisScale( yLeft, 0.0,100.0,10); //添加网格 QwtPlotGrid *grid = new QwtPlotGrid; grid->setPen(QPen(Qt::gray, 0, Qt::DotLine)); grid->attach(this); curve1=new QwtPlotCurve(); //设置曲线的颜色和粗细 curve1->setPen(QColor(255,0,0),2); } MyPlot::~MyPlot() { delete curve1; } void MyPlot::slotDrawLine(QVector<double> Ydata) { clear(); curve1->setSamples(xData,Ydata); curve1->attach(this); this->replot(); } void MyPlot::clear() { curve1->detach();//删除曲线 this->replot(); }
3、为了模拟动态曲线,我在主界面建立一个存放纵坐标数据的Vector,然后用定时器每次触发往里面存一个随机数,当容器大小==101时,就把第一个数pop出去。
每次修改纵坐标容器的数据时,就发送一个绘图信号,该信号连接了MyPlot类里实现的那个槽函数。主界面的代码非常简单。
头文件:
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include <QTimer> #include <QVector> #include "myplot.h" QT_BEGIN_NAMESPACE namespace Ui { class MainWindow; } QT_END_NAMESPACE class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget *parent = nullptr); ~MainWindow(); signals: void sendData(QVector<double> data); private slots: void on_pushButton_clicked();//UI界面放了个QPushButton,点击转到槽后自动生成的槽函数 void slotAddData();//连接定时器,用于动态改变纵坐标容器 private: Ui::MainWindow *ui; QVector<double> data;//纵坐标容器 QTimer *changeDataTimer; MyPlot *plot; //自己写的画图类 }; #endif // MAINWINDOW_H
源码如下:
#include "mainwindow.h" #include "ui_mainwindow.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); plot=new MyPlot(this); plot->setTitle("测试"); plot->move(0,0); plot->setFixedSize(this->width(),0.5*this->height()); changeDataTimer=new QTimer(this); connect(changeDataTimer,&QTimer::timeout, this,&MainWindow::slotAddData); connect(this,&MainWindow::sendData, plot,&MyPlot::slotDrawLine); } MainWindow::~MainWindow() { delete ui; } void MainWindow::slotAddData() { data.push_back(rand()%101); if(data.size()==101) { data.pop_front(); } emit sendData(data); } void MainWindow::on_pushButton_clicked() { changeDataTimer->start(100); }
最后实现的样子: