一、项目结构
fileparser.h
代码语言:javascript复制#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
代码语言:javascript复制#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
代码语言:javascript复制#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
代码语言:javascript复制fileparser.cpp
代码语言:javascript复制#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
代码语言:javascript复制#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
代码语言:javascript复制#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)));
}
}
代码语言:javascript复制ui界面
二、测试用数据格式
文件以txt格式保存
代码语言:javascript复制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位
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/181196.html原文链接:https://javaforall.cn