2025-04-01T17:25:11

This commit is contained in:
yuntang 2025-04-01 17:25:12 +08:00
parent 8f1d0427d3
commit fc961c8e0b
8 changed files with 147 additions and 137 deletions

View File

@ -17,7 +17,8 @@
} }
], ],
"externalConsole": false, "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"
} }
] ]
} }

View File

@ -10,6 +10,12 @@ QPointF PeakPoint::_leftSelectedPoint,PeakPoint::_rightSelectedPoint;
void PeakPoint::setExperimentData(const QVector<FileManager::ExperimentData> &dataVtr) void PeakPoint::setExperimentData(const QVector<FileManager::ExperimentData> &dataVtr)
{ {
_dataVtr = 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(){ QPointF PeakPoint::findPeakPoint(){
@ -20,13 +26,9 @@ QPointF PeakPoint::findPeakPoint(){
} }
QPointF uniquePeak; QPointF uniquePeak;
// 初始化为 float 类型能表示的最小负数,确保能处理负数 y 值 float maxDiff = -std::numeric_limits<float>::infinity();
float maxY = -std::numeric_limits<float>::infinity();
bool isPeak = false;
#if 1 for (int i = 0; i < n; ++i) {
// 直接在遍历过程中找出最大波峰
for (int i = 10; i < n - 10; ++i) { // 从第11个点开始到倒数第11个点结束
const float currentX = _dataVtr.at(i).sampleTemp; const float currentX = _dataVtr.at(i).sampleTemp;
const float currentY = _dataVtr.at(i).dsc; const float currentY = _dataVtr.at(i).dsc;
@ -37,31 +39,18 @@ QPointF PeakPoint::findPeakPoint(){
break; break;
} }
bool isPeak = true; // 计算当前点与左选择点 y 值的差值
// 比较当前点与前后10个点的y值 float diffLeft = std::abs(currentY - _leftSelectedPoint.y());
for (int j = 1; j <= 10; ++j) { // 计算当前点与右选择点 y 值的差值
const float preY = _dataVtr.at(i - j).dsc; float diffRight = std::abs(currentY - _rightSelectedPoint.y());
const float lastY = _dataVtr.at(i + j).dsc; // 取两个差值中的较大值
float currentDiff = std::max(diffLeft, diffRight);
if (currentY < preY || currentY < lastY) { if (currentDiff > maxDiff) {
isPeak = false; maxDiff = currentDiff;
break; uniquePeak = QPointF(currentX, currentY);
}
}
if(isPeak){
#if 1
float absY = std::abs(currentY);
if(absY > maxY){
maxY = absY;
uniquePeak = QPointF(currentX,currentY);
// logde<<"preY:"<<preY<<",lastY:"<<lastY;
}
#endif
} }
} }
#endif
_peakPoint = uniquePeak; _peakPoint = uniquePeak;
@ -125,24 +114,25 @@ QPair<QPointF, QPointF> PeakPoint::calculateMaxDiffPointRight()
return calculateMaxDiffPointDetail(MaxDiffPointDetailType::Right); return calculateMaxDiffPointDetail(MaxDiffPointDetailType::Right);
} }
float PeakPoint::findClosestY(float targetX) #if 0
QPointF PeakPoint::findClosestY(float targetX)
{ {
float minDiff = std::numeric_limits<float>::max(); float minDiff = std::numeric_limits<float>::max();
float closestY = 0.0; QPointF resultPointF;
for(FileManager::ExperimentData &ed:_dataVtr){ for(FileManager::ExperimentData &ed:_dataVtr){
// 计算当前 x 与目标 x 的差值的绝对值
float diff = std::abs(ed.sampleTemp - targetX); float diff = std::abs(ed.sampleTemp - targetX);
// 更新最小差值和对应的 y 值
if (diff < minDiff) { if (diff < minDiff) {
minDiff = diff; minDiff = diff;
closestY = ed.dsc; resultPointF = QPointF(ed.sampleTemp,ed.dsc);
} }
} }
return closestY; return resultPointF;
} }
#endif
#if 0
QPointF PeakPoint::findClosestPointByX(float x) { QPointF PeakPoint::findClosestPointByX(float x) {
int left = 0; int left = 0;
int right = _dataVtr.size() - 1; int right = _dataVtr.size() - 1;
@ -169,18 +159,23 @@ QPointF PeakPoint::findClosestPointByX(float x) {
return targetPoint; return targetPoint;
} }
#endif
void PeakPoint::setRegionPointX(const float left, const float right) void PeakPoint::setRegionPointX(const float left, const float right)
{ {
logde<<"select point param left,right:"<<left<<","<<right;
_leftSelectedPoint = findClosestPointByX(left); _leftSelectedPoint = findClosestPointByX(left);
_rightSelectedPoint = findClosestPointByX(right); _rightSelectedPoint = findClosestPointByX(right);
findPeakPoint(); _peakPoint = findPeakPoint();
logde<<"peak point:"<<_peakPoint.x()<<","<<_peakPoint.y();
//根据峰谷重置选择点。
updateStartEndPoint(); updateStartEndPoint();
qDebug()<<"left,right select point:"<<_leftSelectedPoint logde<<"select point left:"<<_leftSelectedPoint.x()<<","<<_leftSelectedPoint.y();
<<","<<_rightSelectedPoint; logde<<"select point right:"<<_rightSelectedPoint.x()<<","<<_rightSelectedPoint.y();
} }
QVector<QPointF> PeakPoint::getPeakPointGroup() QVector<QPointF> PeakPoint::getPeakPointGroup()
@ -272,11 +267,16 @@ QPair<QPointF, QPointF> PeakPoint::calculateStartAndEndPoint()
logde<<"b1:"<<leftMaxDiffPointPair.first.x()<<","<<leftMaxDiffPointPair.first.y(); logde<<"b1:"<<leftMaxDiffPointPair.first.x()<<","<<leftMaxDiffPointPair.first.y();
logde<<"b2:"<<leftMaxDiffPointPair.second.x()<<","<<leftMaxDiffPointPair.second.y(); logde<<"b2:"<<leftMaxDiffPointPair.second.x()<<","<<leftMaxDiffPointPair.second.y();
logde<<"b3:"<<rightMaxDiffPointPair.first.x()<<","<<rightMaxDiffPointPair.first.y();
logde<<"b4:"<<rightMaxDiffPointPair.second.x()<<","<<rightMaxDiffPointPair.second.y();
QPointF startPoint = calculateIntersection(_leftSelectedPoint,_rightSelectedPoint, QPointF startPoint = calculateIntersection(_leftSelectedPoint,_rightSelectedPoint,
leftMaxDiffPointPair.first,leftMaxDiffPointPair.second); leftMaxDiffPointPair.first,
leftMaxDiffPointPair.second);
QPointF endPoint = calculateIntersection(_leftSelectedPoint,_rightSelectedPoint, QPointF endPoint = calculateIntersection(_leftSelectedPoint,_rightSelectedPoint,
rightMaxDiffPointPair.first,rightMaxDiffPointPair.second); rightMaxDiffPointPair.first,
rightMaxDiffPointPair.second);
return qMakePair(startPoint,endPoint); return qMakePair(startPoint,endPoint);
} }
@ -298,13 +298,12 @@ void PeakPoint::updateStartEndPoint()
_rightSelectedPoint.setY(ed.dsc); _rightSelectedPoint.setY(ed.dsc);
} }
} }
} }
} }
QString PeakPoint::textFormat(const float enthalpyValue, QString PeakPoint::textFormatPeakPoint(const float enthalpyValue,
const float peakValue, const float peakValue,
const float startPoint, const float startPoint,
const float endPoint) const float endPoint)
{ {
return QString("峰的综合信息:\n" return QString("峰的综合信息:\n"
"焓值:%1 J/g \n" "焓值:%1 J/g \n"
@ -341,8 +340,36 @@ QPointF PeakPoint::calculateIntersection(const QPointF p1,const QPointF p2,
} }
} }
QPointF PeakPoint::findClosestPointByX(const float targetX)
{
float minDiff = std::numeric_limits<float>::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<QPointF, QPointF> PeakPoint::getStartAndEndPoint()
{
FileManager::ExperimentData startPoint = _dataVtr.at(0);
FileManager::ExperimentData endPoint = _dataVtr.at(_dataVtr.size() - 1);
return qMakePair<QPointF,QPointF>(
QPointF(startPoint.sampleTemp,startPoint.dsc),
QPointF(endPoint.sampleTemp,endPoint.dsc));
}

View File

@ -5,16 +5,18 @@
#include "filemanager.h" #include "filemanager.h"
namespace PeakPoint{ namespace PeakPoint{
void setExperimentData(const QVector<FileManager::ExperimentData>&); void setExperimentData(const QVector<FileManager::ExperimentData>&);
QPair<QPointF,QPointF> getStartAndEndPoint();
void setRegionPointX(const float,const float); void setRegionPointX(const float,const float);
float findClosestY(float targetX); QPointF findClosestPointByX(const float);
QPointF findPeakPoint(); QPointF findPeakPoint();
QString textFormat(const float enthalpyValue, QString textFormatPeakPoint(const float enthalpyValue,
const float peakValue, const float peakValue,
const float startPoint, const float startPoint,
const float endPoint); const float endPoint);
QString textFormatNumbericalLabel(const QPointF);
QPair<QPointF,QPointF> calculateStartAndEndPoint(); QPair<QPointF,QPointF> calculateStartAndEndPoint();
double calculateArea(); double calculateArea();
@ -30,7 +32,6 @@ QPair<QPointF,QPointF> calculateMaxDiffPointDetail(const MaxDiffPointDetailType
QPointF calculateIntersection(const QPointF p1,const QPointF p2, QPointF calculateIntersection(const QPointF p1,const QPointF p2,
const QPointF p3, const QPointF p4); const QPointF p3, const QPointF p4);
QPointF findClosestPointByX(float target);
QVector<QPointF> getPeakPointGroup(); QVector<QPointF> getPeakPointGroup();
extern QVector<FileManager::ExperimentData> _dataVtr; extern QVector<FileManager::ExperimentData> _dataVtr;

View File

@ -95,6 +95,9 @@ void MainWindow::connections()
_centralWidget,&CentralWidget::slotAnalysisSettingUndo); _centralWidget,&CentralWidget::slotAnalysisSettingUndo);
connect(_analysisSettingWidget,&AnalysisSettingForm::sigCancel, connect(_analysisSettingWidget,&AnalysisSettingForm::sigCancel,
_centralWidget,&CentralWidget::slotAnalysisSettingCancel); _centralWidget,&CentralWidget::slotAnalysisSettingCancel);
connect(_centralWidget,&CentralWidget::sigRightDockWidgetHide,
[&](){ _rightWidget->hide(); });
} }
void MainWindow::setActionEnable(const bool flag) void MainWindow::setActionEnable(const bool flag)

View File

@ -45,6 +45,7 @@ AnalysisSettingForm::AnalysisSettingForm(QWidget *parent) :
layout->addLayout(buttonLayout); layout->addLayout(buttonLayout);
layout->addStretch(1); layout->addStretch(1);
// //
#if 0
connect(_applyButton,&QPushButton::clicked, connect(_applyButton,&QPushButton::clicked,
this,&AnalysisSettingForm::slotApply); this,&AnalysisSettingForm::slotApply);
connect(_confirmButton,&QPushButton::clicked, connect(_confirmButton,&QPushButton::clicked,
@ -53,6 +54,15 @@ AnalysisSettingForm::AnalysisSettingForm(QWidget *parent) :
this,&AnalysisSettingForm::slotUndo); this,&AnalysisSettingForm::slotUndo);
connect(_cancelButton,&QPushButton::clicked, connect(_cancelButton,&QPushButton::clicked,
this,&AnalysisSettingForm::slotCancel); 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); // 设置范围 _leftBorderSpinBox->setRange(0.0, 10000.0); // 设置范围
_rightBorderSpinBox->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() void AnalysisSettingForm::slotApply()
{ {
emit sigApply(); emit sigApply();
@ -79,15 +90,18 @@ void AnalysisSettingForm::slotApply()
void AnalysisSettingForm::slotConfirm() void AnalysisSettingForm::slotConfirm()
{ {
emit sigConfirm();
hide();
} }
void AnalysisSettingForm::slotUndo() void AnalysisSettingForm::slotUndo()
{ {
emit sigUndo();
} }
void AnalysisSettingForm::slotCancel() void AnalysisSettingForm::slotCancel()
{ {
emit sigCancel();
hide();
} }
#endif

View File

@ -21,10 +21,12 @@ signals:
public slots: public slots:
void slotRecvLineXCoord(const int,const double); void slotRecvLineXCoord(const int,const double);
private slots: private slots:
#if 0
void slotApply(); void slotApply();
void slotUndo(); void slotUndo();
void slotConfirm(); void slotConfirm();
void slotCancel(); void slotCancel();
#endif
private: private:
QDoubleSpinBox *_leftBorderSpinBox,*_rightBorderSpinBox; QDoubleSpinBox *_leftBorderSpinBox,*_rightBorderSpinBox;
QLineEdit *_thresholdLineEdit; QLineEdit *_thresholdLineEdit;

View File

@ -81,7 +81,7 @@ void CentralWidget::setAnalysisMode(const CentralWidget::AnalysisMode mode)
_nanlysisMode = mode; _nanlysisMode = mode;
} }
#endif #endif
_nanlysisMode = mode; _nanlysisMode = mode;
switch (mode) switch (mode)
{ {
@ -147,14 +147,6 @@ void CentralWidget::slotRecvAnalysisFileName(const QString &fileName)
return; return;
} }
#if 0
//判断界面上是不是有曲线,有的话先删除。
_customPlot->clearGraphs();
// 创建画布,设置画布上的点数据
_customPlot->addGraph();
#endif
PeakPoint::setExperimentData(_dataVtr); PeakPoint::setExperimentData(_dataVtr);
// 设置坐标轴标签 // 设置坐标轴标签
@ -187,7 +179,11 @@ void CentralWidget::slotAnalysisSettingApply()
switch (_nanlysisMode) { switch (_nanlysisMode) {
case AnalysisMode::NumericalLabel: case AnalysisMode::NumericalLabel:
{ {
drawText(_line1->point1->coords(),"11111"); QPointF selectPoint = PeakPoint::findClosestPointByX(
_line1->point1->coords().x());
drawText(selectPoint,PeakPoint::textFormatNumbericalLabel(selectPoint));
break; break;
} }
case AnalysisMode::PeakSynthesisAnalysis: case AnalysisMode::PeakSynthesisAnalysis:
@ -205,12 +201,13 @@ void CentralWidget::slotAnalysisSettingApply()
QPointF peakPoint = PeakPoint::findPeakPoint(); QPointF peakPoint = PeakPoint::findPeakPoint();
// qDebug()<<"peak point:"<<point; // qDebug()<<"peak point:"<<point;
//start point and end point //start point and end point
QPair<QPointF, QPointF> startEndPointPair = PeakPoint::calculateStartAndEndPoint(); QPair<QPointF, QPointF> startEndPointPair =
PeakPoint::calculateStartAndEndPoint();
drawText(peakPoint,PeakPoint::textFormat(enthalpyValue, drawText(peakPoint,PeakPoint::textFormatPeakPoint(enthalpyValue,
peakPoint.x(), peakPoint.x(),
startEndPointPair.first.x(), startEndPointPair.first.x(),
startEndPointPair.second.x())); startEndPointPair.second.x()));
// //
break; break;
} }
@ -221,17 +218,25 @@ void CentralWidget::slotAnalysisSettingApply()
void CentralWidget::slotAnalysisSettingConfirm() void CentralWidget::slotAnalysisSettingConfirm()
{ {
slotAnalysisSettingApply();
setAnalysisMode(CentralWidget::AnalysisMode::None);
_line1->setVisible(false);
emit sigRightDockWidgetHide();
} }
void CentralWidget::slotAnalysisSettingUndo() void CentralWidget::slotAnalysisSettingUndo()
{ {
clearData(ClearDataMode::Undo);
} }
void CentralWidget::slotAnalysisSettingCancel() void CentralWidget::slotAnalysisSettingCancel()
{ {
clearData(ClearDataMode::Undo);
setAnalysisMode(CentralWidget::AnalysisMode::None);
_line1->setVisible(false);
emit sigRightDockWidgetHide();
} }
void CentralWidget::slotAnalysisSettingLineXPoint(const int index, const double) void CentralWidget::slotAnalysisSettingLineXPoint(const int index, const double)
@ -392,8 +397,8 @@ void CentralWidget::fillGraph(const double x1, const double x2)
{ {
//todo.未寻找x1\x2之间最大值。 //todo.未寻找x1\x2之间最大值。
double y1 = PeakPoint::findClosestY(x1); double y1 = PeakPoint::findClosestPointByX(x1).y();
double y2 = PeakPoint::findClosestY(x2); double y2 = PeakPoint::findClosestPointByX(x2).y();
QVector<double> xVtr,yVtr; QVector<double> xVtr,yVtr;
xVtr.push_back(x1); xVtr.push_back(x1);
@ -416,19 +421,21 @@ void CentralWidget::fillGraph(const double x1, const double x2)
_customPlot->replot(); _customPlot->replot();
} }
void CentralWidget::clearData(const CentralWidget::ClearDataMode mode)
void CentralWidget::clearAllData()
{ {
#if 1 if(mode == ClearDataMode::All){
// Set lines visiable false. // Clear the data of graph.
_line1->setVisible(false); if (_customPlot->graphCount() > 0 && _graph)
_line2->setVisible(false); {
_graph->setData(QVector<double>(), QVector<double>());
}
// Clear the data of graph. // Set lines visiable false.
if (_customPlot->graphCount() > 0 && _graph) _line1->setVisible(false);
{ _line2->setVisible(false);
_graph->setData(QVector<double>(), QVector<double>());
} }
// Clear filled area.
_graph->setBrush(QBrush(Qt::transparent)); _graph->setBrush(QBrush(Qt::transparent));
// Clear graph on plot. // Clear graph on plot.
@ -451,60 +458,9 @@ void CentralWidget::clearAllData()
// 重绘图表以显示更改 // 重绘图表以显示更改
_customPlot->replot(); _customPlot->replot();
#endif }
#if 0 void CentralWidget::clearAllData()
// 删除不需要的 Item {
for (auto *item : itemsToRemove) { clearData(ClearDataMode::All);
_customPlot->removeItem(item);
delete item;
}
_customPlot->replot();
//
if (_customPlot->graphCount() > 0 && _graph)
{
// 清除第一个图表上的数据
_graph->setData(QVector<double>(), QVector<double>());
}
_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
} }

View File

@ -29,12 +29,14 @@ public:
signals: signals:
void sigContextMenuShow(const QPoint); void sigContextMenuShow(const QPoint);
void sigSendLineXCoord(const int,const double); void sigSendLineXCoord(const int,const double);
void sigRightDockWidgetHide();
public slots: public slots:
void slotModeModify(const Global::Mode); void slotModeModify(const Global::Mode);
void slotRecvCommonData(const CommonData&); void slotRecvCommonData(const CommonData&);
void slotRecvAnalysisFileName(const QString&); void slotRecvAnalysisFileName(const QString&);
//analysis setting //analysis setting
void slotAnalysisSettingLineXPoint(const int index,const double); void slotAnalysisSettingLineXPoint(const int index,const double);
void slotAnalysisSettingApply(); void slotAnalysisSettingApply();
void slotAnalysisSettingConfirm(); void slotAnalysisSettingConfirm();
void slotAnalysisSettingUndo(); void slotAnalysisSettingUndo();
@ -45,8 +47,12 @@ protected:
private: private:
void setEventHandlerEnable(const bool); void setEventHandlerEnable(const bool);
void drawText(const QPointF,const QString); void drawText(const QPointF,const QString);
// double findClosestY(double targetX);
void fillGraph(const double x1,const double x2); void fillGraph(const double x1,const double x2);
enum ClearDataMode{
All,
Undo
};
void clearData(const ClearDataMode);
private: private:
AnalysisMode _nanlysisMode; AnalysisMode _nanlysisMode;
QCustomPlot *_customPlot; QCustomPlot *_customPlot;