Qt5--QcustomPlot使用實時動態顯示總結

序言

 一般來說,要想動態顯示需要利用定時器進行數據更新。

  • 動態顯示–模擬數據–X軸固定時間
  • 動態顯示–模擬數據–X軸滾動時間

動態顯示–模擬數據–非真實時間

在這裏插入圖片描述

mainwindows.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    QTimer *timer = new QTimer(this);
    timer->start(1000);
    connect(timer,SIGNAL(timeout()),this,SLOT(Time_Update()));
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::Time_Update(void)
{
    QTime t;
    t=QTime::currentTime();
    qsrand(QTime(0, 0, 0).secsTo(QTime::currentTime()));
    cnt=qrand()%50;
    Show_Plot(ui->widget);
}

void MainWindow::Show_Plot(QCustomPlot *customPlot)
{
    QVector<double> key(10);
    QVector<double> value(10);
    QVector<double> value2(10);


    for(int i=0; i<9; i++)
    {
        num[i] = num[i+1];
    }
    num[9] = cnt;
    for(int i=0;i<10;i++)
    {
        key[i]   = i;
        value[i]  = num[i];
        value2[i]  = num[i]+5;
    }
    customPlot->addGraph();
    customPlot->graph(0)->setPen(QPen(Qt::red));
    customPlot->graph(0)->setData(key,value);

    customPlot->addGraph();
    customPlot->graph(1)->setPen(QPen(Qt::black));
    customPlot->graph(1)->setData(key,value2);

    customPlot->xAxis->setLabel("Time(s)");
    customPlot->yAxis->setLabel("uA");

    customPlot->xAxis->setRange(0,10);
    customPlot->yAxis->setRange(0,100);
    customPlot->replot();
}

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QDebug>
#include "qcustomplot.h"

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
    void Show_Plot(QCustomPlot *customPlot);

public slots:
    void Time_Update(void);

private:
    Ui::MainWindow *ui;
    QCustomPlot *customPlot;
    double num[10]; // 緩衝區
    int cnt;
};

#endif // MAINWINDOW_H

動態顯示–模擬數據–X軸滾動時間

在這裏插入圖片描述

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    QTimer *timer = new QTimer(this);
    timer->start(1000);
    connect(timer,SIGNAL(timeout()),this,SLOT(Time_Update2()));
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::Time_Update(void)
{
    QTime t;
    t=QTime::currentTime();
    qsrand(QTime(0, 0, 0).secsTo(QTime::currentTime()));
    cnt=qrand()%50;
    Show_Plot2(ui->widget);
}

void MainWindow::Show_Plot(QCustomPlot *customPlot)
{
    QVector<double> key(10);
    QVector<double> value(10);
    QVector<double> value2(10);
    double now = QDateTime::currentDateTime().toTime_t();
    srand(8);

    for(int i=0; i<9; i++)
    {
        num[i] = num[i+1]; // 長江後浪推前浪:前消後加
    }
    num[9] = cnt;  // 更新的值加在後面
    for(int i=0;i<10;i++)
    {
        key[i]   = now+i;
        value[i]  = num[i];
        value2[i]  = num[i]+5;
    }
    customPlot->addGraph();
    customPlot->graph(0)->setPen(QPen(Qt::red));
    customPlot->graph(0)->setData(key,value);

    customPlot->addGraph();
    customPlot->graph(1)->setPen(QPen(Qt::black));
    customPlot->graph(1)->setData(key,value2);


    QSharedPointer<QCPAxisTickerDateTime> dateTicker(new QCPAxisTickerDateTime);
    dateTicker->setDateTimeFormat("hh:mm:ss"); // yyyy-MM-dd hh:mm:ss
    customPlot->xAxis->setTicker(dateTicker);
    //customPlot->xAxis->setTickLabelRotation(30); // 設置30斜着顯示

    customPlot->xAxis->setLabel("Time(s)");
    customPlot->yAxis->setLabel("uA");

    customPlot->xAxis->setRange(now, now+20);
    customPlot->yAxis->setRange(0,80);
    customPlot->replot();
}

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QDebug>
#include "qcustomplot.h"

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
    
    void Show_Plot(QCustomPlot *customPlot);

public slots:
    void Time_Update(void);

private:
    Ui::MainWindow *ui;
    QCustomPlot *customPlot;
    double num[10];  // 緩衝區
    int cnt;  // 寫入的值
};

#endif // MAINWINDOW_H

最好的一個狀態

在這裏插入圖片描述
mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"


MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    cnt = 0;

    QSharedPointer<QCPAxisTickerDateTime> dateTicker(new QCPAxisTickerDateTime);//日期做X軸
    dateTicker->setDateTimeFormat("hh:mm:ss.zzz\nyyyy-MM-dd");//日期格式(可參考QDateTime::fromString()函數)
    ui->plot->xAxis->setTicker(dateTicker);//設置X軸爲時間軸
    ui->plot->xAxis->setTickLabels(true);//顯示刻度標籤
    
    ui->plot->addGraph(ui->plot->xAxis, ui->plot->yAxis);
    
    ui->plot->setInteractions(QCP::iRangeDrag //可平移
                            | QCP::iRangeZoom //可滾輪縮放
                            | QCP::iSelectLegend );//可選中圖例
    ui->plot->yAxis->setRange(-1.5, 1.5);


    refreshTimer = startTimer(30, Qt::CoarseTimer);
    sampleTimer = startTimer(500, Qt::CoarseTimer);

    tLast = getNow();

    lastPoint.setX(getNow());
    lastPoint.setY(qSin(lastPoint.x()));
}

void MainWindow::timerEvent(QTimerEvent *event)
{
    Q_UNUSED(event);

    if(event->timerId() == refreshTimer)//30ms
    {
        double xHigh = getNow() - 0.5;
        ui->plot->xAxis->setRange(xHigh - ui->plot->xAxis->range().size(), xHigh);
        ui->plot->replot();
    }


    if(event->timerId() == sampleTimer)//500ms
    {
        newPoint.setX(getNow());
        newPoint.setY(qSin(100 * lastPoint.x()));//模擬收到新的採樣點
        cnt = 0;
        qDebug() << newPoint.x() <<  newPoint.y();

        /*在新的點和上一個採樣點之間,線性插值100個點,但並不立即顯示*/
        /*這裏以線性插值爲例。其餘類型的插值只需替換這一部分即可*/
        int n = 100;
        double dx = (newPoint.x() - lastPoint.x()) / 100.0;//線性插值
        double dy = (newPoint.y() - lastPoint.y()) / 100.0;//線性插值
        for(int i = 1; i <= n; i++)
        {
            ui->plot->graph(0)->addData(lastPoint.x() + dx * i, lastPoint.y() + dy * i);
        }
        lastPoint.setX(newPoint.x());
        lastPoint.setY(newPoint.y());
    }
}

double MainWindow::getNow()
{
    return (double)(QDateTime::currentMSecsSinceEpoch()) / 1000.0;
}


MainWindow::~MainWindow()
{
    delete ui;
}

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include "qcustomplot.h"
#include <QPointF>
#include <QDateTime>
#include <qDebug>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();


protected:

    void timerEvent(QTimerEvent *event);

private:
    Ui::MainWindow *ui;
    double getNow();

    int refreshTimer;//刷新圖像的定時器
    int sampleTimer;//模擬採樣的定時器
    double tLast;
    QPointF newPoint;
    QPointF lastPoint;
    int cnt;

};

#endif // MAINWINDOW_H

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章