From fc961c8e0b88172a819ef4c113c8956cb8ad11eb Mon Sep 17 00:00:00 2001 From: yuntang <123@qq.com> Date: Tue, 1 Apr 2025 17:25:12 +0800 Subject: [PATCH] 2025-04-01T17:25:11 --- src/.vscode/launch.json | 3 +- src/data/peakpoint.cpp | 115 ++++++++++++++++++------------ src/data/peakpoint.h | 9 +-- src/mainwindow.cpp | 3 + src/ui/analysissettingform.cpp | 20 +++++- src/ui/analysissettingform.h | 2 + src/ui/centralwidget.cpp | 124 +++++++++++---------------------- src/ui/centralwidget.h | 8 ++- 8 files changed, 147 insertions(+), 137 deletions(-) diff --git a/src/.vscode/launch.json b/src/.vscode/launch.json index 86cd9ef..a3f8fa1 100644 --- a/src/.vscode/launch.json +++ b/src/.vscode/launch.json @@ -17,7 +17,8 @@ } ], "externalConsole": false, - "miDebuggerPath": "D:/qt/Qt5.14.2/5.14.2/mingw73_64/bin/gdb.exe" + "miDebuggerPath": "D:/qt/Qt5.14.2/5.14.2/mingw73_64/bin/gdb.exe", + "visualizerFile": "c:\\Users\\sunqu\\AppData\\Roaming\\Trae CN\\User\\workspaceStorage\\7f93734217a2e383fe34beaf49d497fe\\tonka3000.qtvsctools\\qt.natvis.xml" } ] } \ No newline at end of file diff --git a/src/data/peakpoint.cpp b/src/data/peakpoint.cpp index 8c49dbf..e678fa5 100644 --- a/src/data/peakpoint.cpp +++ b/src/data/peakpoint.cpp @@ -10,6 +10,12 @@ QPointF PeakPoint::_leftSelectedPoint,PeakPoint::_rightSelectedPoint; void PeakPoint::setExperimentData(const QVector &dataVtr) { _dataVtr = dataVtr; + + FileManager::ExperimentData startPoint = _dataVtr.at(0); + FileManager::ExperimentData endPoint = _dataVtr.at(_dataVtr.size() - 1); + + _leftSelectedPoint = QPointF(startPoint.sampleTemp,startPoint.dsc); + _rightSelectedPoint = QPointF(endPoint.sampleTemp,endPoint.dsc); } QPointF PeakPoint::findPeakPoint(){ @@ -20,13 +26,9 @@ QPointF PeakPoint::findPeakPoint(){ } QPointF uniquePeak; - // 初始化为 float 类型能表示的最小负数,确保能处理负数 y 值 - float maxY = -std::numeric_limits::infinity(); - bool isPeak = false; + float maxDiff = -std::numeric_limits::infinity(); -#if 1 - // 直接在遍历过程中找出最大波峰 - for (int i = 10; i < n - 10; ++i) { // 从第11个点开始,到倒数第11个点结束 + for (int i = 0; i < n; ++i) { const float currentX = _dataVtr.at(i).sampleTemp; const float currentY = _dataVtr.at(i).dsc; @@ -37,31 +39,18 @@ QPointF PeakPoint::findPeakPoint(){ break; } - bool isPeak = true; - // 比较当前点与前后10个点的y值 - for (int j = 1; j <= 10; ++j) { - const float preY = _dataVtr.at(i - j).dsc; - const float lastY = _dataVtr.at(i + j).dsc; + // 计算当前点与左选择点 y 值的差值 + float diffLeft = std::abs(currentY - _leftSelectedPoint.y()); + // 计算当前点与右选择点 y 值的差值 + float diffRight = std::abs(currentY - _rightSelectedPoint.y()); + // 取两个差值中的较大值 + float currentDiff = std::max(diffLeft, diffRight); - if (currentY < preY || currentY < lastY) { - isPeak = false; - break; - } - } - - if(isPeak){ -#if 1 - float absY = std::abs(currentY); - if(absY > maxY){ - maxY = absY; - uniquePeak = QPointF(currentX,currentY); - - // logde<<"preY:"< maxDiff) { + maxDiff = currentDiff; + uniquePeak = QPointF(currentX, currentY); } } -#endif _peakPoint = uniquePeak; @@ -125,24 +114,25 @@ QPair PeakPoint::calculateMaxDiffPointRight() return calculateMaxDiffPointDetail(MaxDiffPointDetailType::Right); } -float PeakPoint::findClosestY(float targetX) +#if 0 +QPointF PeakPoint::findClosestY(float targetX) { float minDiff = std::numeric_limits::max(); - float closestY = 0.0; + QPointF resultPointF; for(FileManager::ExperimentData &ed:_dataVtr){ - // 计算当前 x 与目标 x 的差值的绝对值 float diff = std::abs(ed.sampleTemp - targetX); - // 更新最小差值和对应的 y 值 if (diff < minDiff) { minDiff = diff; - closestY = ed.dsc; + resultPointF = QPointF(ed.sampleTemp,ed.dsc); } } - return closestY; + return resultPointF; } +#endif +#if 0 QPointF PeakPoint::findClosestPointByX(float x) { int left = 0; int right = _dataVtr.size() - 1; @@ -169,18 +159,23 @@ QPointF PeakPoint::findClosestPointByX(float x) { return targetPoint; } +#endif void PeakPoint::setRegionPointX(const float left, const float right) { + logde<<"select point param left,right:"< PeakPoint::getPeakPointGroup() @@ -272,11 +267,16 @@ QPair PeakPoint::calculateStartAndEndPoint() logde<<"b1:"<::max(); + QPointF resultPointF; + for(FileManager::ExperimentData &ed:_dataVtr){ + float diff = std::abs(ed.sampleTemp - targetX); + if (diff < minDiff) { + minDiff = diff; + resultPointF = QPointF(ed.sampleTemp,ed.dsc); + } + } + return resultPointF; +} +QString PeakPoint::textFormatNumbericalLabel(const QPointF point) +{ + return QString("数值:\n" + "%1℃,%2" + ).arg(QString::number(point.x(), 'f', 3)) + .arg(QString::number(point.y(), 'f', 3)); +} +QPair PeakPoint::getStartAndEndPoint() +{ + FileManager::ExperimentData startPoint = _dataVtr.at(0); + FileManager::ExperimentData endPoint = _dataVtr.at(_dataVtr.size() - 1); + return qMakePair( + QPointF(startPoint.sampleTemp,startPoint.dsc), + QPointF(endPoint.sampleTemp,endPoint.dsc)); +} diff --git a/src/data/peakpoint.h b/src/data/peakpoint.h index 8060b35..2d41925 100644 --- a/src/data/peakpoint.h +++ b/src/data/peakpoint.h @@ -5,16 +5,18 @@ #include "filemanager.h" - namespace PeakPoint{ void setExperimentData(const QVector&); + +QPair getStartAndEndPoint(); void setRegionPointX(const float,const float); -float findClosestY(float targetX); +QPointF findClosestPointByX(const float); QPointF findPeakPoint(); -QString textFormat(const float enthalpyValue, +QString textFormatPeakPoint(const float enthalpyValue, const float peakValue, const float startPoint, const float endPoint); +QString textFormatNumbericalLabel(const QPointF); QPair calculateStartAndEndPoint(); double calculateArea(); @@ -30,7 +32,6 @@ QPair calculateMaxDiffPointDetail(const MaxDiffPointDetailType QPointF calculateIntersection(const QPointF p1,const QPointF p2, const QPointF p3, const QPointF p4); -QPointF findClosestPointByX(float target); QVector getPeakPointGroup(); extern QVector _dataVtr; diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 7e5992a..e157ba3 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -95,6 +95,9 @@ void MainWindow::connections() _centralWidget,&CentralWidget::slotAnalysisSettingUndo); connect(_analysisSettingWidget,&AnalysisSettingForm::sigCancel, _centralWidget,&CentralWidget::slotAnalysisSettingCancel); + + connect(_centralWidget,&CentralWidget::sigRightDockWidgetHide, + [&](){ _rightWidget->hide(); }); } void MainWindow::setActionEnable(const bool flag) diff --git a/src/ui/analysissettingform.cpp b/src/ui/analysissettingform.cpp index 60a5ae3..d0e6216 100644 --- a/src/ui/analysissettingform.cpp +++ b/src/ui/analysissettingform.cpp @@ -45,6 +45,7 @@ AnalysisSettingForm::AnalysisSettingForm(QWidget *parent) : layout->addLayout(buttonLayout); layout->addStretch(1); // +#if 0 connect(_applyButton,&QPushButton::clicked, this,&AnalysisSettingForm::slotApply); connect(_confirmButton,&QPushButton::clicked, @@ -53,6 +54,15 @@ AnalysisSettingForm::AnalysisSettingForm(QWidget *parent) : this,&AnalysisSettingForm::slotUndo); connect(_cancelButton,&QPushButton::clicked, this,&AnalysisSettingForm::slotCancel); +#endif + connect(_applyButton,&QPushButton::clicked, + this,&AnalysisSettingForm::sigApply); + connect(_confirmButton,&QPushButton::clicked, + this,&AnalysisSettingForm::sigConfirm); + connect(_undoButton,&QPushButton::clicked, + this,&AnalysisSettingForm::sigUndo); + connect(_cancelButton,&QPushButton::clicked, + this,&AnalysisSettingForm::sigCancel); // _leftBorderSpinBox->setRange(0.0, 10000.0); // 设置范围 _rightBorderSpinBox->setRange(0.0, 10000.0); // 设置范围 @@ -72,6 +82,7 @@ void AnalysisSettingForm::slotRecvLineXCoord(const int index, const double point } } +#if 0 void AnalysisSettingForm::slotApply() { emit sigApply(); @@ -79,15 +90,18 @@ void AnalysisSettingForm::slotApply() void AnalysisSettingForm::slotConfirm() { - + emit sigConfirm(); + hide(); } void AnalysisSettingForm::slotUndo() { - + emit sigUndo(); } void AnalysisSettingForm::slotCancel() { - + emit sigCancel(); + hide(); } +#endif diff --git a/src/ui/analysissettingform.h b/src/ui/analysissettingform.h index 255808f..ef4708e 100644 --- a/src/ui/analysissettingform.h +++ b/src/ui/analysissettingform.h @@ -21,10 +21,12 @@ signals: public slots: void slotRecvLineXCoord(const int,const double); private slots: +#if 0 void slotApply(); void slotUndo(); void slotConfirm(); void slotCancel(); +#endif private: QDoubleSpinBox *_leftBorderSpinBox,*_rightBorderSpinBox; QLineEdit *_thresholdLineEdit; diff --git a/src/ui/centralwidget.cpp b/src/ui/centralwidget.cpp index 8f60a97..38cc7e0 100644 --- a/src/ui/centralwidget.cpp +++ b/src/ui/centralwidget.cpp @@ -81,7 +81,7 @@ void CentralWidget::setAnalysisMode(const CentralWidget::AnalysisMode mode) _nanlysisMode = mode; } #endif - _nanlysisMode = mode; + _nanlysisMode = mode; switch (mode) { @@ -147,14 +147,6 @@ void CentralWidget::slotRecvAnalysisFileName(const QString &fileName) return; } -#if 0 - //判断界面上是不是有曲线,有的话先删除。 - _customPlot->clearGraphs(); - - // 创建画布,设置画布上的点数据 - _customPlot->addGraph(); -#endif - PeakPoint::setExperimentData(_dataVtr); // 设置坐标轴标签 @@ -187,7 +179,11 @@ void CentralWidget::slotAnalysisSettingApply() switch (_nanlysisMode) { case AnalysisMode::NumericalLabel: { - drawText(_line1->point1->coords(),"11111"); + QPointF selectPoint = PeakPoint::findClosestPointByX( + _line1->point1->coords().x()); + + drawText(selectPoint,PeakPoint::textFormatNumbericalLabel(selectPoint)); + break; } case AnalysisMode::PeakSynthesisAnalysis: @@ -205,12 +201,13 @@ void CentralWidget::slotAnalysisSettingApply() QPointF peakPoint = PeakPoint::findPeakPoint(); // qDebug()<<"peak point:"< startEndPointPair = PeakPoint::calculateStartAndEndPoint(); + QPair startEndPointPair = + PeakPoint::calculateStartAndEndPoint(); - drawText(peakPoint,PeakPoint::textFormat(enthalpyValue, - peakPoint.x(), - startEndPointPair.first.x(), - startEndPointPair.second.x())); + drawText(peakPoint,PeakPoint::textFormatPeakPoint(enthalpyValue, + peakPoint.x(), + startEndPointPair.first.x(), + startEndPointPair.second.x())); // break; } @@ -221,17 +218,25 @@ void CentralWidget::slotAnalysisSettingApply() void CentralWidget::slotAnalysisSettingConfirm() { + slotAnalysisSettingApply(); + setAnalysisMode(CentralWidget::AnalysisMode::None); + _line1->setVisible(false); + emit sigRightDockWidgetHide(); } void CentralWidget::slotAnalysisSettingUndo() { - + clearData(ClearDataMode::Undo); } void CentralWidget::slotAnalysisSettingCancel() { + clearData(ClearDataMode::Undo); + setAnalysisMode(CentralWidget::AnalysisMode::None); + _line1->setVisible(false); + emit sigRightDockWidgetHide(); } void CentralWidget::slotAnalysisSettingLineXPoint(const int index, const double) @@ -392,8 +397,8 @@ void CentralWidget::fillGraph(const double x1, const double x2) { //todo.未寻找x1\x2之间最大值。 - double y1 = PeakPoint::findClosestY(x1); - double y2 = PeakPoint::findClosestY(x2); + double y1 = PeakPoint::findClosestPointByX(x1).y(); + double y2 = PeakPoint::findClosestPointByX(x2).y(); QVector xVtr,yVtr; xVtr.push_back(x1); @@ -416,19 +421,21 @@ void CentralWidget::fillGraph(const double x1, const double x2) _customPlot->replot(); } - -void CentralWidget::clearAllData() +void CentralWidget::clearData(const CentralWidget::ClearDataMode mode) { -#if 1 - // Set lines visiable false. - _line1->setVisible(false); - _line2->setVisible(false); + if(mode == ClearDataMode::All){ + // Clear the data of graph. + if (_customPlot->graphCount() > 0 && _graph) + { + _graph->setData(QVector(), QVector()); + } - // Clear the data of graph. - if (_customPlot->graphCount() > 0 && _graph) - { - _graph->setData(QVector(), QVector()); + // Set lines visiable false. + _line1->setVisible(false); + _line2->setVisible(false); } + + // Clear filled area. _graph->setBrush(QBrush(Qt::transparent)); // Clear graph on plot. @@ -451,60 +458,9 @@ void CentralWidget::clearAllData() // 重绘图表以显示更改 _customPlot->replot(); -#endif - -#if 0 - // 删除不需要的 Item - for (auto *item : itemsToRemove) { - _customPlot->removeItem(item); - delete item; - } - _customPlot->replot(); - // - if (_customPlot->graphCount() > 0 && _graph) - { - // 清除第一个图表上的数据 - _graph->setData(QVector(), QVector()); - } - - _customPlot->clearItems(); // 清除所有 QCPItem 对象 - _customPlot->replot(); // 刷新显示 -#endif - -#if 0 - // 从后向前遍历更安全 - for (int i = _customPlot->itemCount()-1; i >= 0; --i) { - QCPItem* item = _customPlot->item(i); - if (item != _line1 && item != _line2) { - _customPlot->removeItem(item); - delete item; - } - } - _customPlot->replot(); -#endif - -#if 0 - // 遍历并删除所有图形元素,除了指定的元素 - for (int i = _customPlot->itemCount() - 1; i >= 0; --i) { - QCPAbstractItem *item = _customPlot->item(i); - if (item != _line1 && item != _line2) { - _customPlot->removeItem(item); - } - } - - // 遍历并删除所有绘图元素,除了指定的元素 - for (int i = _customPlot->graphCount() - 1; i >= 0; --i) { - QCPGraph *graph = _customPlot->graph(i); - if (graph != _graph) { - _customPlot->removeGraph(graph); - } - } - - // 遍历并删除所有文本元素 - for (int i = _customPlot->textLayoutCount() - 1; i >= 0; --i) { - QCPTextElement *textElement = _customPlot->textLayout(i); - _customPlot->removeTextLayout(textElement); - } - -#endif +} + +void CentralWidget::clearAllData() +{ + clearData(ClearDataMode::All); } diff --git a/src/ui/centralwidget.h b/src/ui/centralwidget.h index 7643140..2c280e5 100644 --- a/src/ui/centralwidget.h +++ b/src/ui/centralwidget.h @@ -29,12 +29,14 @@ public: signals: void sigContextMenuShow(const QPoint); void sigSendLineXCoord(const int,const double); + void sigRightDockWidgetHide(); public slots: void slotModeModify(const Global::Mode); void slotRecvCommonData(const CommonData&); void slotRecvAnalysisFileName(const QString&); //analysis setting void slotAnalysisSettingLineXPoint(const int index,const double); + void slotAnalysisSettingApply(); void slotAnalysisSettingConfirm(); void slotAnalysisSettingUndo(); @@ -45,8 +47,12 @@ protected: private: void setEventHandlerEnable(const bool); void drawText(const QPointF,const QString); -// double findClosestY(double targetX); void fillGraph(const double x1,const double x2); + enum ClearDataMode{ + All, + Undo + }; + void clearData(const ClearDataMode); private: AnalysisMode _nanlysisMode; QCustomPlot *_customPlot;