QCustomPlot 使用示例

QCustomPlot 使用示例一、项目结构fileparser.h#ifndefFILEPARSER_H#defineFILEPARSER_H#include<QObject>structstructReferInfo{doublepitch_input;doubleheading;doublepitch;doubleroll;doubleairSpeed_indicated;doubleaccelerationOverLoad_

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

一、项目结构

在这里插入图片描述
fileparser.h

#ifndef FILEPARSER_H
#define FILEPARSER_H
#include <QObject>

struct structReferInfo
{ 
   
    double a;
    double b;
    double c;
    double d;
    double e;
    double f;
};

class fileParser: public QObject
{ 
   
    Q_OBJECT
public:
    fileParser();

    void readFromFile(QString filePath, QVector<QString>& lines);
    void parseFile(std::map<QString, structReferInfo>& referInfoMap, QVector<QString> lines);

private:

    structReferInfo s_referInfo;
};

#endif // FILEPARSER_H

function.h

#ifndef FUNCTION_H
#define FUNCTION_H
#include <QDateTime>
#include <QString>

inline void qstringToTime(QString timeStr, QDateTime& time)
{ 
   
    QString dateTimeStr = timeStr;
    dateTimeStr = dateTimeStr.trimmed();

    if(!dateTimeStr.isEmpty())
    { 
   
        time = QDateTime::fromString(dateTimeStr, "yyyy-MM-dd hh:mm:ss.zzz");
    }
}

#endif // FUNCTION_H

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <fileparser.h>
#include <QDateTime>
#include <QLabel>

QT_BEGIN_NAMESPACE
namespace Ui { 
    class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{ 
   
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

    void getData();

private:
    void initUi();

    void setCustomPlotProperty();

    void initVectorSize(int size);

    void setCustomPlotData();

private slots:
    void on_actionOpenFile_triggered();

    void doubleClicked(QMouseEvent *event);

    void on_actionJPG_triggered();

private:
    Ui::MainWindow *ui;

    QDateTime timeStart, timeFinished;

    fileParser m_fileParser;
    QVector<QString> lines;
    std::map<QString, structReferInfo> referInfoMap;

    QLabel *m_statusLabel;
};
#endif // MAINWINDOW_H

fileparser.cpp
#include "fileparser.h"
#include <QFile>
#include <QTextStream>
#include <QMessageBox>

static int count = 0;

fileParser::fileParser()
{ 
   

}

void fileParser::readFromFile(QString filePath, QVector<QString>& lines)
{ 
   
    QFile file(filePath);

    if(!file.open(QIODevice::ReadOnly | QIODevice::Text))
    { 
   
        return;
    }

    QString line;
    QTextStream in(&file);
    line = in.readLine();

    while(!line.isNull())
    { 
   
        lines.push_back(line);
        line = in.readLine();
    }
    file.close();
}

void fileParser::parseFile(std::map<QString, structReferInfo>& referInfoMap, QVector<QString> lines)
{ 
   
    for ( QVector<QString>::const_iterator it = lines.begin(); it != lines.end(); it++ )
    { 
   
        QStringList strList = it->split(",");
        if(strList.size() != 7)
        { 
   
            count++;
            continue;
        }

        QString time = strList[0];
        s_referInfo.a= strList[1].toFloat();
        s_referInfo.b= strList[2].toFloat();
        s_referInfo.c= strList[3].toFloat();
        s_referInfo.d= strList[4].toFloat();
        s_referInfo.e= strList[5].toFloat();
        s_referInfo.f= strList[6].toFloat();
        referInfoMap.insert(std::pair<QString, structReferInfo>(time, s_referInfo));
    }

    if(count > 0)
    { 
   
        QString temp = QString::fromLocal8Bit("该文件中共有%1个数据错误,已过滤错误数据!").arg(count);
        QMessageBox::warning(NULL, "warning", temp, QMessageBox::Yes);

    }
}

main.cpp

#include "mainwindow.h"

#include <QApplication>

int main(int argc, char *argv[])
{ 
   
    QApplication a(argc, argv);
    MainWindow w;
    w.setWindowTitle("drawTool");

    //w.setWindowFlags(Qt::MSWindowsFixedSizeDialogHint);


    w.showMaximized();
    return a.exec();
}

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "QCustomPlot/qcustomplot.h"
#include "function.h"

#define SERIES_COUNT 6

QCustomPlot *customPlot[SERIES_COUNT];
QVector<double> X;
QVector<double> Y[SERIES_COUNT];

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

    initUi();

    setCustomPlotProperty();
}

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

void MainWindow::initUi()
{ 
   
    for(int i = 0; i < SERIES_COUNT; i++)
    { 
   
        customPlot[i] = new QCustomPlot(ui->scrollArea->widget());
        ui->verticalLayout->addWidget(customPlot[i]);
        connect(customPlot[i], SIGNAL(mouseDoubleClick(QMouseEvent *)), this, SLOT(doubleClicked(QMouseEvent *)));
    }

    m_statusLabel = new QLabel(ui->statusbar);
}

void MainWindow::doubleClicked(QMouseEvent *event)
{ 
   
    Q_UNUSED(event);

    for(int i = 0; i < SERIES_COUNT; i++)
    { 
   
        if(customPlot[i]->hasFocus())
        { 
   
            customPlot[i]->graph(0)->rescaleAxes();
            customPlot[i]->replot();
        }
    }
}

void MainWindow::setCustomPlotProperty()
{ 
   
    QSharedPointer<QCPAxisTickerDateTime> timer(new QCPAxisTickerDateTime);
    timer->setDateTimeFormat("hh:mm:ss.zzz");
    timer->setTickCount(20);

    QFont font;
    font.setPixelSize(20);

    for(int i = 0; i < SERIES_COUNT; i++)
    { 
   
        customPlot[i]->addGraph();
        //customPlot[i]->setMinimumHeight(600);
        customPlot[i]->setFixedHeight(600);

        customPlot[i]->xAxis->setTicker(timer);
        customPlot[i]->xAxis->setLabel("time");

        // 边框右侧和上侧均显示刻度线,但不显示刻度值:
// customPlot[i]->xAxis2->setVisible(true);
// customPlot[i]->xAxis2->setTickLabels(false);
// customPlot[i]->yAxis2->setVisible(true);
// customPlot[i]->yAxis2->setTickLabels(false);

        customPlot[i]->xAxis->setTickLabelFont(font);
        customPlot[i]->xAxis->setLabelFont(font);
        customPlot[i]->yAxis->setTickLabelFont(font);
        customPlot[i]->yAxis->setLabelFont(font);

        customPlot[i]->legend->setVisible(true);
        // 使上下两个X轴的范围总是相等,使左右两个Y轴的范围总是相等
        connect(customPlot[i]->xAxis, SIGNAL(rangeChanged(QCPRange)), customPlot[i]->xAxis2, SLOT(setRange(QCPRange)));
        connect(customPlot[i]->yAxis, SIGNAL(rangeChanged(QCPRange)), customPlot[i]->yAxis2, SLOT(setRange(QCPRange)));
    }

    customPlot[0]->graph(0)->setPen(QPen(Qt::red, 1));
    customPlot[1]->graph(0)->setPen(QPen(Qt::darkGray, 1));
    customPlot[2]->graph(0)->setPen(QPen(Qt::green, 1));
    customPlot[3]->graph(0)->setPen(QPen(Qt::blue, 1));
    customPlot[4]->graph(0)->setPen(QPen(Qt::darkYellow, 1));
    customPlot[5]->graph(0)->setPen(QPen(Qt::cyan, 1));

    customPlot[0]->yAxis->setLabel("value");
    customPlot[1]->yAxis->setLabel("value");
    customPlot[2]->yAxis->setLabel("value");
    customPlot[3]->yAxis->setLabel("value");
    customPlot[4]->yAxis->setLabel("value");
    customPlot[5]->yAxis->setLabel("value");

    customPlot[0]->graph(0)->setName("a");
    customPlot[1]->graph(0)->setName("b");
    customPlot[2]->graph(0)->setName("c");
    customPlot[3]->graph(0)->setName("d");
    customPlot[4]->graph(0)->setName("e");
    customPlot[5]->graph(0)->setName("f");
}


void MainWindow::on_actionOpenFile_triggered()
{ 
   
    QString fileName = QFileDialog::getOpenFileName(nullptr, "Open File", "", "TXT File(*.txt)");
    if(fileName.isEmpty())
    { 
   
        return;
    }

    m_statusLabel->setText(fileName);
    m_statusLabel->adjustSize();

    lines.resize(0);
    referInfoMap.erase(referInfoMap.begin(),referInfoMap.end());

    m_fileParser.readFromFile(fileName, lines);
    m_fileParser.parseFile(referInfoMap, lines);

    getData();
    setCustomPlotData();
}

void MainWindow::getData()
{ 
   
    int i = 0, size = 0;

    std::map<QString, structReferInfo>::const_iterator iterFirst = referInfoMap.begin();
    std::map<QString,structReferInfo>::reverse_iterator iterLast = referInfoMap.rbegin();       //返回最后一个元素

    size = (int)referInfoMap.size();
    initVectorSize(size);

    qstringToTime(iterFirst->first, timeStart);
    qstringToTime(iterLast->first, timeFinished);

    std::map<QString, structReferInfo>::const_iterator iter = referInfoMap.begin();
    for (iter = referInfoMap.begin(); iter != referInfoMap.end(); iter++)
    { 
   
        QDateTime time;
        qstringToTime(iter->first, time);
        double A= iter->second.a;
        double B= iter->second.b;
        double C= iter->second.c;
        double D= iter->second.d;
        double E= iter->second.e;
        double F= iter->second.f;

        //X[i] = time.toTime_t(); //没有毫秒数据
        X[i] = time.toMSecsSinceEpoch() / 1000.0;           //有毫秒数据,但是要除以1000,hh::mm::ss.zzz格式化的时候才能识别毫秒
        Y[0][i] = A;
        Y[1][i] = B;
        Y[2][i] = C;
        Y[3][i] = D;
        Y[4][i] = E;
        Y[5][i] = F;        

        i++;
    }
}

void MainWindow::setCustomPlotData()
{ 
   
    // 把已存在的数据填充进graph的数据区
    for(int i = 0 ; i < SERIES_COUNT; i++)
    { 
   
        customPlot[i]->graph(0)->setData(X, Y[i]);

        customPlot[i]->graph(0)->rescaleAxes();                          //自动调整XY轴的范围,以便显示出graph(0)中所有的点

        customPlot[i]->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom | QCP::iSelectPlottables);         // 支持鼠标拖拽轴的范围、滚动缩放轴的范围,左键点选图层(每条曲线独占一个图层)

        customPlot[i]->replot();
    }
}

void MainWindow::initVectorSize(int size)
{ 
   
    X.resize(size);
    for(int i = 0; i < SERIES_COUNT; i++)
    { 
   
        Y[i].resize(size);
    }
}

void MainWindow::on_actionJPG_triggered()
{ 
   
    QString savePath = QCoreApplication::applicationDirPath();
    savePath += "/outputData/JPG/";

    QDir dir;
    if(!dir.exists(savePath))
    { 
   
        dir.mkdir(savePath);
    }

    bool isOK;
    QString text = QInputDialog::getText(NULL, QString::fromLocal8Bit("设置"), QString::fromLocal8Bit("请设置要保存的文件名"), QLineEdit::Normal, "fileName", &isOK);

    if(!isOK)
    { 
   
        QMessageBox::warning(NULL, QString::fromLocal8Bit("警告"), QString::fromLocal8Bit("未输入文件名!文件未保存!"), QMessageBox::Yes);
        return;
    }

    QString filePath = savePath+ text + QString("%1.jpg");
    QFileInfo fileInfo(filePath);
    if(fileInfo.isFile())
    { 
   
        QMessageBox::warning(NULL, QString::fromLocal8Bit("警告"), QString::fromLocal8Bit("文件已存在!"), QMessageBox::Yes);
        return;
    }

    for(int i = 0; i < SERIES_COUNT; i++)
    { 
   
        customPlot[i]->saveJpg(filePath.arg(i), 0, 0);
    }

    if (QMessageBox::Yes == QMessageBox::question(NULL, QString::fromLocal8Bit("完成"), QString::fromLocal8Bit("保存成功,是否打开查看?"), QMessageBox::Yes | QMessageBox::No))
    { 
   
        QDesktopServices::openUrl(QUrl("file:///" + QDir::toNativeSeparators(savePath)));
    }
}

ui界面

在这里插入图片描述

二、测试用数据格式

文件以txt格式保存

2021-04-30 14:43:01.598,-6.10352e-05,291.097,0.0343483,-0.254098,590.425,-19.7816
2021-04-30 14:43:01.894,-6.10352e-05,291.038,0.0404533,-0.29129,589.273,-18.3748
2021-04-30 14:43:01.896,-6.10352e-05,291.038,0.0404533,-0.29129,589.273,-18.3748
2021-04-30 14:43:01.921,-6.10352e-05,290.778,0.0755395,-0.411844,582.944,-12.3173
2021-04-30 14:43:01.933,-6.10352e-05,290.765,0.0782369,-0.415599,582.477,-11.9309
2021-04-30 14:43:01.944,-6.10352e-05,290.759,0.0795836,-0.417224,582.243,-11.763
2021-04-30 14:43:01.956,-6.10352e-05,290.753,0.080929,-0.418838,582.009,-11.6061
2021-04-30 14:43:01.964,-6.10352e-05,290.747,0.0822826,-0.42044,581.775,-11.4324
2021-04-30 14:43:01.976,-6.10352e-05,290.742,0.0836427,-0.42203,581.542,-11.2519
2021-04-30 14:43:01.994,-6.10352e-05,290.737,0.0850009,-0.423148,581.309,-11.0893
2021-04-30 14:43:02.008,-6.10352e-05,290.729,0.0871385,-0.425021,580.923,-10.8135
2021-04-30 14:43:02.020,-6.10352e-05,290.724,0.0885049,-0.425659,580.739,-10.6823
2021-04-30 14:43:02.035,-6.10352e-05,290.72,0.0898726,-0.42675,580.506,-10.5237
2021-04-30 14:43:02.047,-6.10352e-05,290.712,0.0921791,-0.427633,580.077,-10.2551
2021-04-30 14:43:02.061,-6.10352e-05,290.709,0.0935521,-0.428249,579.882,-10.1267
2021-04-30 14:43:02.079,-6.10352e-05,290.703,0.095621,-0.429162,579.476,-9.87097
2021-04-30 14:43:02.094,-6.10352e-05,290.698,0.097765,-0.429591,579.122,-9.65878
2021-04-30 14:43:02.110,-6.10352e-05,290.694,0.0991455,-0.430185,578.942,-9.54891
2021-04-30 14:43:02.128,-6.10352e-05,290.689,0.101797,-0.430475,578.49,-9.28378
2021-04-30 14:43:02.144,-6.10352e-05,290.686,0.103182,-0.4306,578.27,-9.15764
2021-04-30 14:43:02.162,-6.10352e-05,290.681,0.105896,-0.430396,577.815,-8.89946
2021-04-30 14:43:02.178,-6.10352e-05,290.677,0.108167,-0.430286,577.403,-8.67594
2021-04-30 14:43:02.194,-6.10352e-05,290.675,0.109559,-0.429933,577.215,-8.57507
2021-04-30 14:43:02.210,-6.10352e-05,290.672,0.112049,-0.429291,576.812,-8.34438
2021-04-30 14:43:02.228,-6.10352e-05,290.671,0.113445,-0.428924,576.606,-8.24013
2021-04-30 14:43:02.246,-6.10352e-05,290.668,0.11624,-0.428175,576.148,-8.00886
2021-04-30 14:43:02.260,-6.10352e-05,290.665,0.118687,-0.427503,575.721,-7.80056
2021-04-30 14:43:02.280,-6.10352e-05,290.664,0.120088,-0.427112,575.522,-7.70508
2021-04-30 14:43:02.294,-6.10352e-05,290.663,0.122894,-0.425854,575.068,-7.49047
2021-04-30 14:43:02.312,-6.10352e-05,290.662,0.124298,-0.425446,574.841,-7.38657
2021-04-30 14:43:02.330,-6.10352e-05,290.661,0.126865,-0.424227,574.408,-7.1915
2021-04-30 14:43:02.346,-6.10352e-05,290.66,0.12955,-0.422952,573.987,-7.00661
2021-04-30 14:43:02.364,-6.10352e-05,290.659,0.130957,-0.422519,573.772,-6.91474
2021-04-30 14:43:02.380,-6.10352e-05,290.659,0.133561,-0.421238,573.37,-6.72936
2021-04-30 14:43:02.394,-6.10352e-05,290.659,0.13497,-0.420324,573.161,-6.64398
2021-04-30 14:43:02.414,-6.10352e-05,290.659,0.137406,-0.419067,572.743,-6.47565
2021-04-30 14:43:02.428,-6.10352e-05,290.659,0.139845,-0.417792,572.357,-6.3234
2021-04-30 14:43:02.447,-6.10352e-05,290.659,0.141255,-0.417317,572.165,-6.24904
2021-04-30 14:43:02.462,-6.10352e-05,290.659,0.144076,-0.415881,571.721,-6.08032
2021-04-30 14:43:02.481,-6.10352e-05,290.659,0.145487,-0.414918,571.5,-5.99758
2021-04-30 14:43:02.497,-6.10352e-05,290.66,0.148309,-0.413445,571.058,-5.83732
2021-04-30 14:43:02.511,-6.10352e-05,290.661,0.15069,-0.412109,570.652,-5.69287
2021-04-30 14:43:02.527,-6.10352e-05,290.661,0.152101,-0.41159,570.467,-5.62847
2021-04-30 14:43:02.543,-6.10352e-05,290.662,0.153512,-0.411066,570.28,-5.55045
2021-04-30 14:43:02.557,-6.10352e-05,290.663,0.15623,-0.409563,569.847,-5.40615
2021-04-30 14:43:02.577,-6.10352e-05,290.663,0.157641,-0.408544,569.637,-5.33715
2021-04-30 14:43:02.593,-6.10352e-05,290.664,0.160462,-0.407444,569.201,-5.19601
2021-04-30 14:43:02.613,-6.10352e-05,290.665,0.16264,-0.406098,568.817,-5.0757
2021-04-30 14:43:02.627,-6.10352e-05,290.667,0.165064,-0.405118,568.465,-4.96738
2021-04-30 14:43:02.643,-6.10352e-05,290.667,0.166474,-0.404541,568.28,-4.91124
2021-04-30 14:43:02.661,-6.10352e-05,290.668,0.169084,-0.403457,567.866,-4.78862
2021-04-30 14:43:02.677,-6.10352e-05,290.67,0.171475,-0.40196,567.486,-4.67872
2021-04-30 14:43:02.693,-6.10352e-05,290.67,0.172883,-0.401357,567.337,-4.62411
2021-04-30 14:43:02.713,-6.10352e-05,290.672,0.175429,-0.40025,566.927,-4.51165
2021-04-30 14:43:02.727,-6.10352e-05,290.673,0.17802,-0.399595,566.539,-4.40635
2021-04-30 14:43:02.743,-6.10352e-05,290.674,0.179425,-0.398966,566.344,-4.35419
2021-04-30 14:43:02.761,-6.10352e-05,290.675,0.181752,-0.397911,565.958,-4.25372
2021-04-30 14:43:02.779,-6.10352e-05,290.676,0.183156,-0.397267,565.785,-4.20889
2021-04-30 14:43:02.793,-6.10352e-05,290.677,0.185963,-0.396455,565.367,-4.10293
2021-04-30 14:43:02.811,-6.10352e-05,290.678,0.187365,-0.395794,565.16,-4.05129
2021-04-30 14:43:02.827,-6.10352e-05,290.679,0.190119,-0.394974,564.751,-3.95035
2021-04-30 14:43:02.843,-6.10352e-05,290.68,0.192398,-0.393869,564.413,-3.85975
2021-04-30 14:43:02.859,-6.10352e-05,290.681,0.193798,-0.39368,564.247,-3.82054

三、结果

在这里插入图片描述

四、完整示例下载

https://download.csdn.net/download/qq_40754866/18910871
运行环境:qt 5.14.2 win10 64位

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/181196.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • oracle_loader类型外部表

    oracle_loader类型外部表1、创建目录(createanydirectory):   SQL>createuseroracleidentifiedbyoracle;用户已创建。SQL>grantdbatooracle;授权成功。SQL>grantcreateanydirectorytooracle;授权成功。SQL>connoracle/oracle

    2022年10月11日
  • googleearth离线地图_谷歌插件离线安装

    googleearth离线地图_谷歌插件离线安装Google离线地图API概要解析发布时间:2018-01-17版权: 1.说明离线地图发布有多种方式均可以实现,可以利用ArcGisServer、GeoServer等构建地图Web服务器,还可以使用谷歌地图、百度地图等API进行地图发布服务。本篇主要简单介绍如何调用Google离线地图API实现地图标注、获取坐标、及其他参数的设置。【如何发布Google离线地图】2.实…

  • UIImageView圆角

    UIImageView圆角

  • Android 绑定服务 bindService[通俗易懂]

    Android 绑定服务 bindService[通俗易懂]绑定服务是客户端–服务器接口中的服务器。组件(如activity)和服务进行绑定后,可以发送请求、接收响应、执行进程间通信(IPC)。不会无限期在后台运行。要提供服务绑定,必须实现onBind()回调方法,该方法返回的IBinder对象定义了客户端用来与服务进行交互的编程接口。客户端可以通过调用bindService()绑定到服务。调用时,必须提供ServiceConnection的实现,后者会…

  • GridView行编辑、更新、取消、删除事件使用方法

    GridView行编辑、更新、取消、删除事件使用方法

  • 干货 | LIDAR、ToF相机、双目相机如何科学选择?「建议收藏」

    干货 | LIDAR、ToF相机、双目相机如何科学选择?「建议收藏」点击“计算机视觉life”关注,置顶更快接收消息!本文阅读时间约5分钟本文翻译自卡内基梅隆大学Chrisasteroid三维视觉技术的选择传感器参数及定义LIDAR&amp;amp;amp;ToF相机&amp;amp;amp;双目相机介绍工作原理优缺点采样数据比较测试及极端情况测试三维成像技术原理和应用想必大家在之前的文章中了解过啦,今天想给大家比较一下LIDAR、ToF相机…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号