关于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);
}

最后实现的样子:

  

 

posted @ 2020-10-16 10:04  量子诗人  阅读(338)  评论(0编辑  收藏  举报
Live2D