From 47a55ee9381db547ebf9f1db8bdf82cbc40036e6 Mon Sep 17 00:00:00 2001 From: yuntang <123@qq.com> Date: Thu, 3 Apr 2025 17:24:29 +0800 Subject: [PATCH] 2025-04-03T17:24:27 --- src/AnalysTool.pro | 13 +- .../{peakpoint.cpp => pointcalculate.cpp} | 155 +++++++----- src/data/{peakpoint.h => pointcalculate.h} | 20 +- src/mainwindow.cpp | 59 +++++ src/mainwindow.h | 24 ++ src/mainwindow.ui | 68 ++++++ src/ui/centralwidget.cpp | 215 ++++++++--------- src/ui/centralwidget.h | 7 +- src/ui/draglinehandler.cpp | 17 +- src/ui/specificheatcomparisonmethodform.cpp | 24 ++ src/ui/specificheatcomparisonmethodform.h | 27 +++ src/ui/specificheatcomparisonmethodform.ui | 223 ++++++++++++++++++ 12 files changed, 666 insertions(+), 186 deletions(-) rename src/data/{peakpoint.cpp => pointcalculate.cpp} (72%) rename src/data/{peakpoint.h => pointcalculate.h} (69%) create mode 100644 src/ui/specificheatcomparisonmethodform.cpp create mode 100644 src/ui/specificheatcomparisonmethodform.h create mode 100644 src/ui/specificheatcomparisonmethodform.ui diff --git a/src/AnalysTool.pro b/src/AnalysTool.pro index e8ec41d..93848b7 100644 --- a/src/AnalysTool.pro +++ b/src/AnalysTool.pro @@ -17,7 +17,7 @@ DEFINES += QT_DEPRECATED_WARNINGS SOURCES += \ data/filemanager.cpp \ - data/peakpoint.cpp \ + data/pointcalculate.cpp \ global.cpp \ logger/logger.cpp \ rightwidget.cpp \ @@ -32,11 +32,12 @@ SOURCES += \ ui/draglinehandler.cpp \ ui/experimentsettingform.cpp \ ui/leftwidget.cpp \ - ui/realtimedataform.cpp + ui/realtimedataform.cpp \ + ui/specificheatcomparisonmethodform.cpp HEADERS += \ data/filemanager.h \ - data/peakpoint.h \ + data/pointcalculate.h \ defines.h \ global.h \ logger/logger.h \ @@ -52,12 +53,14 @@ HEADERS += \ ui/draglinehandler.h \ ui/experimentsettingform.h \ ui/leftwidget.h \ - ui/realtimedataform.h + ui/realtimedataform.h \ + ui/specificheatcomparisonmethodform.h FORMS += \ mainwindow.ui \ ui/experimentsettingform.ui \ - ui/realtimedataform.ui + ui/realtimedataform.ui \ + ui/specificheatcomparisonmethodform.ui INCLUDEPATH += serialport \ ui \ diff --git a/src/data/peakpoint.cpp b/src/data/pointcalculate.cpp similarity index 72% rename from src/data/peakpoint.cpp rename to src/data/pointcalculate.cpp index e678fa5..5a1437b 100644 --- a/src/data/peakpoint.cpp +++ b/src/data/pointcalculate.cpp @@ -1,16 +1,20 @@ #include -#include "peakpoint.h" +#include "pointcalculate.h" #include "logger.h" -QVectorPeakPoint:: _dataVtr; -QPointF PeakPoint::_peakPoint; -QPointF PeakPoint::_leftSelectedPoint,PeakPoint::_rightSelectedPoint; +QVectorPointCalculate:: _dataVtr; +QPointF PointCalculate::_peakPoint; +QPointF PointCalculate::_leftSelectedPoint,PointCalculate::_rightSelectedPoint; -void PeakPoint::setExperimentData(const QVector &dataVtr) +void PointCalculate::setExperimentData(const QVector &dataVtr) { _dataVtr = dataVtr; + if(_dataVtr.empty()) { + return; + } + FileManager::ExperimentData startPoint = _dataVtr.at(0); FileManager::ExperimentData endPoint = _dataVtr.at(_dataVtr.size() - 1); @@ -18,7 +22,18 @@ void PeakPoint::setExperimentData(const QVector &da _rightSelectedPoint = QPointF(endPoint.sampleTemp,endPoint.dsc); } -QPointF PeakPoint::findPeakPoint(){ +std::vector PointCalculate::movingAverage(const std::vector& data, int windowSize) { + std::vector smoothedData; + for (size_t i = 0; i < data.size(); ++i) { + if (i + windowSize <= data.size()) { + float sum = std::accumulate(data.begin() + i, data.begin() + i + windowSize, 0.0); + smoothedData.push_back(sum / windowSize); + } + } + return smoothedData; +} + +QPointF PointCalculate::getPeakPoint(){ int n = _dataVtr.size(); if (n < 3) { @@ -59,8 +74,8 @@ QPointF PeakPoint::findPeakPoint(){ return uniquePeak; } -QPair PeakPoint::calculateMaxDiffPointDetail( - const PeakPoint::MaxDiffPointDetailType type) +QPair PointCalculate::calculateMaxDiffPointDetail( + const PointCalculate::MaxDiffPointDetailType type) { #if 1 float maxDiff = std::numeric_limits::min(); @@ -104,18 +119,18 @@ QPair PeakPoint::calculateMaxDiffPointDetail( } -QPair PeakPoint::calculateMaxDiffPointLeft() +QPair PointCalculate::calculateMaxDiffPointLeft() { return calculateMaxDiffPointDetail(MaxDiffPointDetailType::Left); } -QPair PeakPoint::calculateMaxDiffPointRight() +QPair PointCalculate::calculateMaxDiffPointRight() { return calculateMaxDiffPointDetail(MaxDiffPointDetailType::Right); } #if 0 -QPointF PeakPoint::findClosestY(float targetX) +QPointF PointCalculate::findClosestY(float targetX) { float minDiff = std::numeric_limits::max(); QPointF resultPointF; @@ -133,7 +148,7 @@ QPointF PeakPoint::findClosestY(float targetX) #endif #if 0 -QPointF PeakPoint::findClosestPointByX(float x) { +QPointF PointCalculate::findClosestPointByX(float x) { int left = 0; int right = _dataVtr.size() - 1; @@ -161,14 +176,14 @@ QPointF PeakPoint::findClosestPointByX(float x) { } #endif -void PeakPoint::setRegionPointX(const float left, const float right) +void PointCalculate::setRegionPointX(const float left, const float right) { logde<<"select point param left,right:"< PeakPoint::getPeakPointGroup() +QVector PointCalculate::getPeakPointGroup() { QVector pointVtr; for(FileManager::ExperimentData& ed:_dataVtr) { @@ -190,19 +205,9 @@ QVector PeakPoint::getPeakPointGroup() return pointVtr; } -double PeakPoint::calculateArea() { +double PointCalculate::calculateArea() { //getPoint group QVector points = getPeakPointGroup(); -#if 0 - for(QPointF point:points){ - qDebug()<<"x,y:"< PeakPoint::calculateStartAndEndPoint() +QPair PointCalculate::calculateStartAndEndPoint() { - QPair leftMaxDiffPointPair = PeakPoint::calculateMaxDiffPointLeft(); - QPair rightMaxDiffPointPair = PeakPoint::calculateMaxDiffPointRight(); - + QPair leftMaxDiffPointPair = PointCalculate::calculateMaxDiffPointLeft(); + QPair rightMaxDiffPointPair = PointCalculate::calculateMaxDiffPointRight(); +#if 0 logde<<"b1:"< PeakPoint::calculateStartAndEndPoint() return qMakePair(startPoint,endPoint); } -void PeakPoint::updateStartEndPoint() +void PointCalculate::updateStartEndPoint() { //需要在a1和a2之间查询是否有高于a1和a2之间的点,若存在,则重新给a1、a2赋值 @@ -300,7 +288,7 @@ void PeakPoint::updateStartEndPoint() } } } -QString PeakPoint::textFormatPeakPoint(const float enthalpyValue, +QString PointCalculate::textFormatPeakPoint(const float enthalpyValue, const float peakValue, const float startPoint, const float endPoint) @@ -317,7 +305,7 @@ QString PeakPoint::textFormatPeakPoint(const float enthalpyValue, } // 计算两条直线的交点 -QPointF PeakPoint::calculateIntersection(const QPointF p1,const QPointF p2, +QPointF PointCalculate::calculateIntersection(const QPointF p1,const QPointF p2, const QPointF p3, const QPointF p4){ // 直线的一般式: A1x + B1y + C1 = 0 和 A2x + B2y + C2 = 0 float A1 = p2.y() - p1.y(); @@ -340,10 +328,10 @@ QPointF PeakPoint::calculateIntersection(const QPointF p1,const QPointF p2, } } -QPointF PeakPoint::findClosestPointByX(const float targetX) +QPointF PointCalculate::getClosestPointByX(const float targetX) { +#if 0 float minDiff = std::numeric_limits::max(); - QPointF resultPointF; for(FileManager::ExperimentData &ed:_dataVtr){ float diff = std::abs(ed.sampleTemp - targetX); @@ -352,11 +340,37 @@ QPointF PeakPoint::findClosestPointByX(const float targetX) resultPointF = QPointF(ed.sampleTemp,ed.dsc); } } +#endif + + int left = 0; + int right = _dataVtr.size() - 1; + + while (left < right) { + int mid = left + (right - left)/2; + const FileManager::ExperimentData& ed = _dataVtr.at(mid); + if(ed.sampleTemp > targetX){ + right = mid; + }else{ + left = mid + 1; + } + } + + // + QPointF resultPointF(_dataVtr.at(left).sampleTemp, + _dataVtr.at(left).dsc); + + if(left > 0 && + std::abs(resultPointF.x() - targetX) > + std::abs(_dataVtr.at(left - 1).sampleTemp - targetX)){ + // + resultPointF = QPointF(_dataVtr.at(left - 1).sampleTemp, + _dataVtr.at(left - 1).dsc); + } return resultPointF; } -QString PeakPoint::textFormatNumbericalLabel(const QPointF point) +QString PointCalculate::textFormatNumbericalLabel(const QPointF point) { return QString("数值:\n" "%1℃,%2" @@ -364,8 +378,11 @@ QString PeakPoint::textFormatNumbericalLabel(const QPointF point) .arg(QString::number(point.y(), 'f', 3)); } -QPair PeakPoint::getStartAndEndPoint() +QPair PointCalculate::getStartAndEndPoint() { + if(_dataVtr.empty()){ + return qMakePair(QPointF(), QPointF()); + } FileManager::ExperimentData startPoint = _dataVtr.at(0); FileManager::ExperimentData endPoint = _dataVtr.at(_dataVtr.size() - 1); @@ -373,3 +390,27 @@ QPair PeakPoint::getStartAndEndPoint() QPointF(startPoint.sampleTemp,startPoint.dsc), QPointF(endPoint.sampleTemp,endPoint.dsc)); } + +QString PointCalculate::textFormatStartPoint(const QPointF point) +{ + return QString("外推起始点:\n" + "%1℃" + ).arg(QString::number(point.x(), 'f', 3)); +} + +QString PointCalculate::textFormatEndPoint(const QPointF point) +{ + return QString("外推终止点:\n" + "%1℃" + ).arg(QString::number(point.x(), 'f', 3)); +} + +QPair PointCalculate::getCurveInflectionPointTangent() +{ + +} + +QVector PointCalculate::getRegionPoints(const float, const float) +{ + +} diff --git a/src/data/peakpoint.h b/src/data/pointcalculate.h similarity index 69% rename from src/data/peakpoint.h rename to src/data/pointcalculate.h index 2d41925..1a4c81d 100644 --- a/src/data/peakpoint.h +++ b/src/data/pointcalculate.h @@ -1,25 +1,32 @@ -#ifndef PEAKPOINT_H -#define PEAKPOINT_H +#ifndef POINTCALCULATE_H +#define POINTCALCULATE_H #include #include "filemanager.h" -namespace PeakPoint{ +namespace PointCalculate{ void setExperimentData(const QVector&); QPair getStartAndEndPoint(); + void setRegionPointX(const float,const float); -QPointF findClosestPointByX(const float); -QPointF findPeakPoint(); +QPointF getClosestPointByX(const float); +QPointF getPeakPoint(); QString textFormatPeakPoint(const float enthalpyValue, const float peakValue, const float startPoint, const float endPoint); QString textFormatNumbericalLabel(const QPointF); +QString textFormatStartPoint(const QPointF); +QString textFormatEndPoint(const QPointF); + QPair calculateStartAndEndPoint(); double calculateArea(); +//​获取曲线拐点处的切线 +QPair getCurveInflectionPointTangent(); +QVector getRegionPoints(const float,const float); //private void updateStartEndPoint(); QPair calculateMaxDiffPointLeft(); @@ -33,10 +40,11 @@ QPair calculateMaxDiffPointDetail(const MaxDiffPointDetailType QPointF calculateIntersection(const QPointF p1,const QPointF p2, const QPointF p3, const QPointF p4); QVector getPeakPointGroup(); +std::vector movingAverage(const std::vector& data, int windowSize); extern QVector _dataVtr; extern QPointF _peakPoint; extern QPointF _leftSelectedPoint,_rightSelectedPoint; } -#endif // PEAKPOINT_H +#endif // POINTCALCULATE_H diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index e157ba3..f91bbff 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -17,6 +17,7 @@ MainWindow::MainWindow(QWidget *parent) _rightWidget(new QDockWidget(this)) ,_analysisSettingWidget(new AnalysisSettingForm(this)) ,_contextMenu(new QMenu(this)) + ,_specificHeatComparisonMethodForm(new SpecificHeatComparisonMethodForm(this)) { ui->setupUi(this); this->setToolTip("....."); @@ -37,6 +38,8 @@ MainWindow::MainWindow(QWidget *parent) connections(); // _expertmentSettingForm->setWindowFlags(_expertmentSettingForm->windowFlags()| Qt::Dialog); + _specificHeatComparisonMethodForm->setWindowFlags(_specificHeatComparisonMethodForm->windowFlags()| Qt::Dialog); + _realTimeDataForm->setWindowFlags(_realTimeDataForm->windowFlags()| Qt::Dialog); // _realTimeDataForm->show(); @@ -203,3 +206,59 @@ void MainWindow::on_actionClearAllData_triggered() { _centralWidget->clearAllData(); } + +void MainWindow::on_actionGlassTransition_triggered() +{ + _rightWidget->show(); + _centralWidget->setAnalysisMode(CentralWidget::AnalysisMode::GlassTransition); +} + +void MainWindow::on_actionOIT_triggered() +{ + +} + +void MainWindow::on_actionSpecificHeatCompMethod_triggered() +{ + _specificHeatComparisonMethodForm->show(); +} + +void MainWindow::on_actionDegreeOfCrystallinity_triggered() +{ + +} + +void MainWindow::on_actionInstrumentParameter_triggered() +{ + +} + +void MainWindow::on_actionInitialMeltingPoint_triggered() +{ + +} + +void MainWindow::on_actionFinalMeltingPoint_triggered() +{ + +} + +void MainWindow::on_actionOITAutoAnalysisParam_triggered() +{ + +} + +void MainWindow::on_actionOITAutoAnalysisMode_triggered() +{ + +} + +void MainWindow::on_actionTimeAxisAnalysisPCTMode_triggered() +{ + +} + +void MainWindow::on_actionDegreeOfCuring_triggered() +{ + +} diff --git a/src/mainwindow.h b/src/mainwindow.h index 79bb693..3d6ef05 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -12,6 +12,7 @@ #include "dataparser.h" #include "rightwidget.h" #include "analysissettingform.h" +#include "specificheatcomparisonmethodform.h" QT_BEGIN_NAMESPACE namespace Ui { class MainWindow; } @@ -42,6 +43,28 @@ private slots: void on_actionPeakSynthesisAnalysis_triggered(); void on_actionClearAllData_triggered(); + void on_actionGlassTransition_triggered(); + + void on_actionOIT_triggered(); + + void on_actionSpecificHeatCompMethod_triggered(); + + void on_actionDegreeOfCrystallinity_triggered(); + + void on_actionInstrumentParameter_triggered(); + + void on_actionInitialMeltingPoint_triggered(); + + void on_actionFinalMeltingPoint_triggered(); + + void on_actionOITAutoAnalysisParam_triggered(); + + void on_actionOITAutoAnalysisMode_triggered(); + + void on_actionTimeAxisAnalysisPCTMode_triggered(); + + void on_actionDegreeOfCuring_triggered(); + private: void connections(); void setActionEnable(const bool); @@ -54,5 +77,6 @@ private: RealTimeDataForm* _realTimeDataForm; QMenu* _contextMenu; AnalysisSettingForm* _analysisSettingWidget; + SpecificHeatComparisonMethodForm* _specificHeatComparisonMethodForm; }; #endif // MAINWINDOW_H diff --git a/src/mainwindow.ui b/src/mainwindow.ui index f0260db..89ac5ab 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -45,9 +45,22 @@ 分析 + + + + + + + + + + + + + @@ -179,6 +192,61 @@ 清除所有数据 + + + 玻璃化转变 + + + + + 氧化诱导期 + + + + + 比热比较法 + + + + + 结晶度 + + + + + 仪器系数 + + + + + 初融点 + + + + + 终融点 + + + + + OIT自动分析参数 + + + + + OIT自动分析模式 + + + + + 时间轴分析峰综合温度模式 + + + + + 固化度 + + diff --git a/src/ui/centralwidget.cpp b/src/ui/centralwidget.cpp index 38cc7e0..4bb780a 100644 --- a/src/ui/centralwidget.cpp +++ b/src/ui/centralwidget.cpp @@ -6,13 +6,13 @@ #include "centralwidget.h" #include "filemanager.h" -#include "peakpoint.h" +#include "pointcalculate.h" #include "logger.h" CentralWidget::CentralWidget(QWidget *parent) : QWidget(parent), _customPlot(new QCustomPlot(this)) - ,_nanlysisMode(AnalysisMode::None) + ,_analysisMode(AnalysisMode::None) { setMouseTracking(true); @@ -74,14 +74,7 @@ CentralWidget::~CentralWidget() void CentralWidget::setAnalysisMode(const CentralWidget::AnalysisMode mode) { -#if 0 - if(_nanlysisMode == mode){ - return; - }else{ - _nanlysisMode = mode; - } -#endif - _nanlysisMode = mode; + _analysisMode = mode; switch (mode) { @@ -89,6 +82,7 @@ void CentralWidget::setAnalysisMode(const CentralWidget::AnalysisMode mode) case AnalysisMode::StartPoint: case AnalysisMode::StopPoint: case AnalysisMode::PeakSynthesisAnalysis: + case AnalysisMode::GlassTransition: setEventHandlerEnable(true); break; default: @@ -138,7 +132,9 @@ void CentralWidget::slotRecvAnalysisFileName(const QString &fileName) { qDebug() << "slotRecvAnalysisFileName" << fileName; - // QVector dataVtr; + // + clearData(ClearDataMode::All); + // _dataVtr.clear(); FileManager::readExperimentFile(fileName, _dataVtr); @@ -146,15 +142,23 @@ void CentralWidget::slotRecvAnalysisFileName(const QString &fileName) { return; } + // + // _customPlot->xAxis->setRange(0, 500); + // _customPlot->yAxis->setRange(-20, 20); + PointCalculate::setExperimentData(_dataVtr); + QPairstartEndPointPair = PointCalculate::getStartAndEndPoint(); - PeakPoint::setExperimentData(_dataVtr); + QPointF endPoint = startEndPointPair.second; + _customPlot->xAxis->setRange(0, endPoint.x() / 3 * 4); + + QPointF peakPoint = PointCalculate::getPeakPoint(); + float absY = std::abs(peakPoint.y()); + _customPlot->yAxis->setRange(- absY * 2,absY *2); // 设置坐标轴标签 _customPlot->yAxis->setLabel("DSC/mW"); _customPlot->xAxis->setLabel("Temp/℃"); - // 设置坐标轴范围,以便我们可以看到全部数据 - _customPlot->xAxis->setRange(0, 500); - _customPlot->yAxis->setRange(-20, 20); + QVector xVtr, yVtr; for (FileManager::ExperimentData &ed : _dataVtr) @@ -176,13 +180,32 @@ void CentralWidget::slotRecvAnalysisFileName(const QString &fileName) void CentralWidget::slotAnalysisSettingApply() { - switch (_nanlysisMode) { + switch (_analysisMode) { case AnalysisMode::NumericalLabel: { - QPointF selectPoint = PeakPoint::findClosestPointByX( + QPointF selectPoint = PointCalculate::getClosestPointByX( _line1->point1->coords().x()); - drawText(selectPoint,PeakPoint::textFormatNumbericalLabel(selectPoint)); + drawText(selectPoint,PointCalculate::textFormatNumbericalLabel(selectPoint)); + + break; + } + case AnalysisMode::StartPoint: + case AnalysisMode::StopPoint:{ + double x1 = _line1->point1->coords().x(); + double x2 = _line2->point1->coords().x(); + PointCalculate::setRegionPointX(x1,x2); + + QPair startEndPointPair = + PointCalculate::calculateStartAndEndPoint(); + + if(_analysisMode == AnalysisMode::StartPoint){ + drawText(startEndPointPair.first, + PointCalculate::textFormatStartPoint(startEndPointPair.first)); + }else{ + drawText(startEndPointPair.second, + PointCalculate::textFormatEndPoint(startEndPointPair.second)); + } break; } @@ -193,24 +216,33 @@ void CentralWidget::slotAnalysisSettingApply() fillGraph(x1,x2); - PeakPoint::setRegionPointX(x1,x2); + PointCalculate::setRegionPointX(x1,x2); //enthalpy - double enthalpyValue = PeakPoint::calculateArea(); + double enthalpyValue = PointCalculate::calculateArea(); //peak - QPointF peakPoint = PeakPoint::findPeakPoint(); - // qDebug()<<"peak point:"< startEndPointPair = - PeakPoint::calculateStartAndEndPoint(); + PointCalculate::calculateStartAndEndPoint(); - drawText(peakPoint,PeakPoint::textFormatPeakPoint(enthalpyValue, + logde<<"start,end:"<setVisible(false); + _line2->setVisible(false); emit sigRightDockWidgetHide(); } @@ -234,7 +268,9 @@ void CentralWidget::slotAnalysisSettingCancel() { clearData(ClearDataMode::Undo); setAnalysisMode(CentralWidget::AnalysisMode::None); + _line1->setVisible(false); + _line2->setVisible(false); emit sigRightDockWidgetHide(); } @@ -277,23 +313,66 @@ void CentralWidget::contextMenuEvent(QContextMenuEvent *event) emit sigContextMenuShow(point); } +void CentralWidget::glassTransitionHandle() +{ + QPointF point1 = PointCalculate::getClosestPointByX(_line1->point1->coords().x()); + QPointF point2 = PointCalculate::getClosestPointByX(_line2->point1->coords().x()); + + logde<<"point1:"<point1->setCoords(point1.x() - 55,point1.y()); + line1->point2->setCoords(point1.x() + 55,point1.y()); + line1->setPen(QPen(Qt::darkGreen)); + line1->setSelectable(false); + line1->setVisible(true); + + QCPItemStraightLine *line2 = new QCPItemStraightLine(_customPlot); + line2->point1->setCoords(point2.x() - 55,point2.y()); + line2->point2->setCoords(point2.x() + 55,point2.y()); + line2->setPen(QPen(Qt::darkGreen)); + line2->setSelectable(false); + line2->setVisible(true); + + _customPlot->replot(); +} + void CentralWidget::setEventHandlerEnable(const bool flag) { logde<<"setEventHandlerEnable..."<setSelected(flag); + line->setVisible(flag); + }; + // todo. 当竖线隐藏时,需要设置不可选择模式。 _eventHandler->setEnable(flag); - _line1->setVisible(flag); - if(AnalysisMode::NumericalLabel != _nanlysisMode){ - _line2->setVisible(flag); +#if 1 + // move line to suitable position. + double xMax = _customPlot->xAxis->range().upper; // X 轴的最大值 + + logde<<"xMax:"<point1->setCoords(xMax / 3,_line1->point1->coords().y()); + _line1->point2->setCoords(xMax / 3,_line1->point2->coords().y()); + + _line2->point1->setCoords(xMax / 3 * 2,_line2->point1->coords().y()); + _line2->point2->setCoords(xMax / 3 * 2,_line2->point2->coords().y()); +#endif + lineVisiableFunc(_line1); + if(AnalysisMode::NumericalLabel != _analysisMode){ + lineVisiableFunc(_line2); } + // _customPlot->replot(); } void CentralWidget::drawText(const QPointF point, const QString text) { - // double y = PeakPoint::findClosestY(x); // 创建标注文字(QCPItemText) QCPItemText *textLabel = new QCPItemText(_customPlot); textLabel->setPositionAlignment(Qt::AlignBottom | Qt::AlignHCenter); // 对齐方式 @@ -314,91 +393,15 @@ void CentralWidget::drawText(const QPointF point, const QString text) // 重绘图表以显示文本标签和箭头 _customPlot->replot(); - -#if 0 - // 创建标注文字(QCPItemText) - QCPItemText *textLabel = new QCPItemText(_customPlot); - textLabel->setPositionAlignment(Qt::AlignBottom|Qt::AlignHCenter); // 对齐方式 - textLabel->position->setType(QCPItemPosition::ptPlotCoords); // 使用数据坐标 - textLabel->position->setCoords(x, - _graph->data()->at(x)->value + 0.5); // 假设标注在 x=5 的点上方 - textLabel->setText("标注文字"); - textLabel->setFont(QFont("Arial", 10)); - textLabel->setPen(QPen(Qt::black)); // 文字边框 - textLabel->setBrush(Qt::white); // 文字背景 - - // 创建指向点的线段(QCPItemLine) - QCPItemLine *arrow = new QCPItemLine(_customPlot); - arrow->start->setParentAnchor(textLabel->bottom); // 线段起点绑定到标注文字底部 - arrow->end->setCoords(x, _graph->data()->at(x)->value); // 线段终点绑定到数据点 - arrow->setHead(QCPLineEnding::esSpikeArrow); // 添加箭头 - arrow->setPen(QPen(Qt::red, 2)); -#endif - -#if 0 - if (!_graph || !_customPlot) { - return; - } - // 创建标注文字(QCPItemText) - QCPItemText *textLabel = new QCPItemText(_customPlot); - textLabel->setPositionAlignment(Qt::AlignBottom|Qt::AlignHCenter); // 对齐方式 - textLabel->position->setType(QCPItemPosition::ptPlotCoords); // 使用数据坐标 - - // 查找最接近 x 的数据点 - auto it = _graph->data()->findBegin(x); - if (it != _graph->data()->end()) { - double y = it->value + 0.5; - textLabel->position->setCoords(x, y); - textLabel->setText(text); - textLabel->setFont(QFont("Arial", 10)); - textLabel->setPen(QPen(Qt::black)); // 文字边框 - textLabel->setBrush(Qt::white); // 文字背景 - - // 创建指向点的线段(QCPItemLine) - QCPItemLine *arrow = new QCPItemLine(_customPlot); - arrow->start->setParentAnchor(textLabel->bottom); // 线段起点绑定到标注文字底部 - arrow->end->setCoords(x, it->value); // 线段终点绑定到数据点 - arrow->setHead(QCPLineEnding::esSpikeArrow); // 添加箭头 - arrow->setPen(QPen(Qt::red, 2)); - } -#endif - } -#if 0 -double CentralWidget::findClosestY(double targetX) { - // 获取曲线数据容器 - QSharedPointer> dataContainer = - _graph->data(); - // 初始化最小差值和对应的 y 值 - double minDiff = std::numeric_limits::max(); - double closestY = 0.0; - - // 遍历数据容器 - for (int i = 0; i < dataContainer->size(); ++i) { - double currentX = dataContainer->at(i)->key; - double currentY = dataContainer->at(i)->value; - - // 计算当前 x 与目标 x 的差值的绝对值 - double diff = std::abs(currentX - targetX); - - // 更新最小差值和对应的 y 值 - if (diff < minDiff) { - minDiff = diff; - closestY = currentY; - } - } - - return closestY; -} -#endif void CentralWidget::fillGraph(const double x1, const double x2) { //todo.未寻找x1\x2之间最大值。 - double y1 = PeakPoint::findClosestPointByX(x1).y(); - double y2 = PeakPoint::findClosestPointByX(x2).y(); + double y1 = PointCalculate::getClosestPointByX(x1).y(); + double y2 = PointCalculate::getClosestPointByX(x2).y(); QVector xVtr,yVtr; xVtr.push_back(x1); diff --git a/src/ui/centralwidget.h b/src/ui/centralwidget.h index 2c280e5..dea6348 100644 --- a/src/ui/centralwidget.h +++ b/src/ui/centralwidget.h @@ -19,7 +19,8 @@ public: NumericalLabel, StartPoint, StopPoint, - PeakSynthesisAnalysis + PeakSynthesisAnalysis, + GlassTransition }; CentralWidget(QWidget *parent = nullptr); ~CentralWidget(); @@ -45,6 +46,7 @@ protected: void timerEvent(QTimerEvent* event); void contextMenuEvent(QContextMenuEvent *event); private: + void glassTransitionHandle(); void setEventHandlerEnable(const bool); void drawText(const QPointF,const QString); void fillGraph(const double x1,const double x2); @@ -54,12 +56,13 @@ private: }; void clearData(const ClearDataMode); private: - AnalysisMode _nanlysisMode; + AnalysisMode _analysisMode; QCustomPlot *_customPlot; QCPGraph* _graph; DragLineHandler* _eventHandler; QCPItemStraightLine *_line1,*_line2; QVector _dataVtr; + QVector _lineVtr; }; #endif // CENTRALWIDGET_H diff --git a/src/ui/draglinehandler.cpp b/src/ui/draglinehandler.cpp index fb0b389..344fdbf 100644 --- a/src/ui/draglinehandler.cpp +++ b/src/ui/draglinehandler.cpp @@ -16,7 +16,7 @@ DragLineHandler::~DragLineHandler() bool DragLineHandler::eventFilter(QObject *obj, QEvent *event) { if(!_enableFlag){ -// qDebug()<<"_enableFlag false."; + // qDebug()<<"_enableFlag false."; #if 0 if(mPlot){ mPlot->setCursor(Qt::ArrowCursor); @@ -29,25 +29,22 @@ bool DragLineHandler::eventFilter(QObject *obj, QEvent *event) { if (event->type() == QEvent::MouseMove) { -// qDebug()<<"mouse move..."; + // qDebug()<<"mouse move..."; QMouseEvent *mouseEvent = static_cast(event); QPoint mousePos = mouseEvent->pos(); -// qDebug()<<"x:"<visible()) || + (nearLine2 && _line2->visible())) { _plot->setCursor(Qt::SplitHCursor); - -// qDebug()<<"mIconLabel visiable."; } else { -// qDebug()<<"mIconLabel not visiable."; - _plot->setCursor(Qt::ArrowCursor); } @@ -67,7 +64,7 @@ bool DragLineHandler::eventFilter(QObject *obj, QEvent *event) } else if (event->type() == QEvent::MouseButtonPress) { -// qDebug()<<"mouse press..."; + // qDebug()<<"mouse press..."; QMouseEvent *mouseEvent = static_cast(event); if (mouseEvent->button() == Qt::LeftButton) @@ -125,7 +122,7 @@ void DragLineHandler::updateSelectedRegion() int index1 = findClosestIndex(xData, x1); int index2 = findClosestIndex(xData, x2); -// qDebug() << "Selected region: [" << xData[index1] << ", " << xData[index2] << "]"; + // qDebug() << "Selected region: [" << xData[index1] << ", " << xData[index2] << "]"; } int DragLineHandler::findClosestIndex(const QVector &data, double target) diff --git a/src/ui/specificheatcomparisonmethodform.cpp b/src/ui/specificheatcomparisonmethodform.cpp new file mode 100644 index 0000000..1b30c53 --- /dev/null +++ b/src/ui/specificheatcomparisonmethodform.cpp @@ -0,0 +1,24 @@ +#include "specificheatcomparisonmethodform.h" +#include "ui_specificheatcomparisonmethodform.h" + +SpecificHeatComparisonMethodForm::SpecificHeatComparisonMethodForm(QWidget *parent) : + QWidget(parent), + ui(new Ui::SpecificHeatComparisonMethodForm) +{ + ui->setupUi(this); +} + +SpecificHeatComparisonMethodForm::~SpecificHeatComparisonMethodForm() +{ + delete ui; +} + +void SpecificHeatComparisonMethodForm::on_pushButtonCalculate_clicked() +{ + +} + +void SpecificHeatComparisonMethodForm::on_pushButtonQuit_clicked() +{ + hide(); +} diff --git a/src/ui/specificheatcomparisonmethodform.h b/src/ui/specificheatcomparisonmethodform.h new file mode 100644 index 0000000..d406fdf --- /dev/null +++ b/src/ui/specificheatcomparisonmethodform.h @@ -0,0 +1,27 @@ +#ifndef SPECIFICHEATCOMPARISONMETHODFORM_H +#define SPECIFICHEATCOMPARISONMETHODFORM_H + +#include + +namespace Ui { +class SpecificHeatComparisonMethodForm; +} + +class SpecificHeatComparisonMethodForm : public QWidget +{ + Q_OBJECT + +public: + explicit SpecificHeatComparisonMethodForm(QWidget *parent = nullptr); + ~SpecificHeatComparisonMethodForm(); + +private slots: + void on_pushButtonCalculate_clicked(); + + void on_pushButtonQuit_clicked(); + +private: + Ui::SpecificHeatComparisonMethodForm *ui; +}; + +#endif // SPECIFICHEATCOMPARISONMETHODFORM_H diff --git a/src/ui/specificheatcomparisonmethodform.ui b/src/ui/specificheatcomparisonmethodform.ui new file mode 100644 index 0000000..39a2ae6 --- /dev/null +++ b/src/ui/specificheatcomparisonmethodform.ui @@ -0,0 +1,223 @@ + + + SpecificHeatComparisonMethodForm + + + + 0 + 0 + 318 + 556 + + + + Form + + + + + 19 + 19 + 281 + 471 + + + + + + + 参数 + + + + + 9 + 30 + 261 + 81 + + + + + + + 温度(℃) + + + + + + + + + + 校正系数 + + + + + + + + + + + + + + 数据文件 + + + + + 9 + 29 + 261 + 81 + + + + + + + 基线 + + + + + + + + + + 标样 + + + + + + + + + + 样品 + + + + + + + + + + + + + + 相关参数 + + + + + 10 + 20 + 261 + 81 + + + + + + + 样品质量 + + + + + + + + + + 标样质量 + + + + + + + + + + 标样比热(J/(g*℃)) + + + + + + + + + + + + + + 计算结果 + + + + + 9 + 29 + 261 + 41 + + + + + + + 样品比热(J/(g*℃)) + + + + + + + + + + + + + + + + 100 + 520 + 80 + 20 + + + + 计算 + + + + + + 200 + 520 + 80 + 20 + + + + 退出 + + + + + +