diff --git a/experiment_data/sample_data/1.xlsx b/experiment_data/sample_data/1.xlsx new file mode 100644 index 0000000..3c6ec53 Binary files /dev/null and b/experiment_data/sample_data/1.xlsx differ diff --git a/experiment_data/sample_data/24-new.xlsx b/experiment_data/sample_data/24-new.xlsx new file mode 100644 index 0000000..4f6eb27 Binary files /dev/null and b/experiment_data/sample_data/24-new.xlsx differ diff --git a/src/data/pointcalculate.cpp b/src/data/pointcalculate.cpp index f9e06ab..9f6a985 100644 --- a/src/data/pointcalculate.cpp +++ b/src/data/pointcalculate.cpp @@ -395,8 +395,13 @@ QPointF PointCalculate::getIntersection(const Line& line1, const Line& line2) { } QPointF PointCalculate::getClosestPointByX(const float targetX) { -#if 1 QPointF resultPointF; + + if(targetX < _dataVtr.first().sampleTemp || + targetX > _dataVtr.last().sampleTemp){ + return resultPointF; + } + float minDiff = std::numeric_limits::max(); for(Global::ExperimentData &ed:_dataVtr){ @@ -408,36 +413,6 @@ QPointF PointCalculate::getClosestPointByX(const float targetX) } return resultPointF; -#endif - -#if 0 - 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; -#endif } QString PointCalculate::textFormatNumbericalLabel(const QPointF point) @@ -563,20 +538,20 @@ QVector PointCalculate::movingAveragePoint(const QVector &poin return result; #endif QVector result; - int n = points.size(); - for (int i = 0; i < n; ++i) { - double sumY = 0.0; - int count = 0; - for (int j = std::max(0, i - windowSize / 2); j <= std::min(n - 1, i + windowSize / 2); ++j) { - sumY += points[j].y(); - count++; - } - if (count > 0) { - double avgY = sumY / count; - result.append(QPointF(points[i].x(), avgY)); // 使用原始的 x 值 - } - } - return result; + int n = points.size(); + for (int i = 0; i < n; ++i) { + double sumY = 0.0; + int count = 0; + for (int j = std::max(0, i - windowSize / 2); j <= std::min(n - 1, i + windowSize / 2); ++j) { + sumY += points[j].y(); + count++; + } + if (count > 0) { + double avgY = sumY / count; + result.append(QPointF(points[i].x(), avgY)); // 使用原始的 x 值 + } + } + return result; } QVector PointCalculate::getNearbyPointGroupByX(const float targetX) { diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 01982a3..b0dd872 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -148,10 +148,10 @@ void MainWindow::connections() connect(_analysisSettingWidget,&AnalysisSettingForm::sigApply, _centralWidget,&CentralWidget::slotAnalysisSettingApply); - connect(_analysisSettingWidget,&AnalysisSettingForm::sigConfirm, - _centralWidget,&CentralWidget::slotAnalysisSettingConfirm); connect(_analysisSettingWidget,&AnalysisSettingForm::sigUndo, _centralWidget,&CentralWidget::slotAnalysisSettingUndo); + connect(_analysisSettingWidget,&AnalysisSettingForm::sigConfirm, + _centralWidget,&CentralWidget::slotAnalysisSettingConfirm); connect(_analysisSettingWidget,&AnalysisSettingForm::sigCancel, _centralWidget,&CentralWidget::slotAnalysisSettingCancel); diff --git a/src/serialport/dataparser.cpp b/src/serialport/dataparser.cpp index d1edb63..1609060 100644 --- a/src/serialport/dataparser.cpp +++ b/src/serialport/dataparser.cpp @@ -41,7 +41,9 @@ bool commonDataParser(const QByteArray &ba, CommonData &cd) QByteArray connectToDevice(const QVector &vtr) { - const int phaseLength = sizeof(Phase); +// const int phaseLength = sizeof(Phase); + const int phaseLength = PHASE_BYTE_SIZE; + const int phaseArrayLength = vtr.size() * phaseLength; char phaseArray[300] = {}; int offset = 0; @@ -86,7 +88,6 @@ QByteArray connectToDevice(const QVector &vtr) memcpy(totalData + 6 + phaseArrayLength, (char *)&crc, sizeof(u16)); // - return QByteArray(totalData, 6 + phaseArrayLength + 2); } diff --git a/src/serialport/protocol.h b/src/serialport/protocol.h index f160ed8..3f1a0db 100644 --- a/src/serialport/protocol.h +++ b/src/serialport/protocol.h @@ -49,7 +49,7 @@ typedef struct control_data float cutoff_temp; float temp_flow; uint16_t constant_temp_time_min; - enum gas_type gas; + enum gas_type gas; // uint8_t }Phase; struct pid_data diff --git a/src/serialport/serialport.cpp b/src/serialport/serialport.cpp index 75b94d2..39c3083 100644 --- a/src/serialport/serialport.cpp +++ b/src/serialport/serialport.cpp @@ -98,7 +98,7 @@ void SerialPort::slotReadData() if(ba.size() == 0){ return; } -#if 0 +#if 1 QString hexData = ba.toHex(' '); // ' ' 作为分隔符,可选参数 qDebug() << "receive info (hex):" << hexData; #endif diff --git a/src/ui/centralwidget.cpp b/src/ui/centralwidget.cpp index ebe468d..f68dd77 100644 --- a/src/ui/centralwidget.cpp +++ b/src/ui/centralwidget.cpp @@ -14,7 +14,7 @@ CentralWidget::CentralWidget(QWidget *parent) : QWidget(parent) ,_customPlot(new QCustomPlot(this)) - ,_analysisMode(AnalysisMode::None) + ,_analysisMode(AnalysisMode::Null) ,_currentCurve(nullptr) { setMouseTracking(true); @@ -91,17 +91,19 @@ CentralWidget::~CentralWidget() void CentralWidget::setAnalysisMode(const CentralWidget::AnalysisMode mode) { - _customPlot->setInteractions(QCP::iSelectPlottables); - _analysisMode = mode; switch (mode) { + case AnalysisMode::Null: + _customPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom | QCP::iSelectPlottables); + break; case AnalysisMode::NumericalLabel: case AnalysisMode::StartPoint: case AnalysisMode::StopPoint: case AnalysisMode::PeakSynthesisAnalysis: case AnalysisMode::GlassTransition: + _customPlot->setInteractions(QCP::iSelectPlottables); setEventHandlerEnable(true); break; default: @@ -158,13 +160,13 @@ void CentralWidget::slotRecvCommonData(const CommonData &cd) // return; // Record data. - logde<<"record data..."; +// logde<<"record data..."; if(!Global::_currentCurveExperimentDataPtr){ logde<<"_currentCurveExperimentDataPtr is nullptr."; exit(0); }else{ - logde<<"add ed..."; +// logde<<"add ed..."; Global::ExperimentData ed; ed.dsc = cd .dsc; @@ -173,9 +175,7 @@ void CentralWidget::slotRecvCommonData(const CommonData &cd) ed.constantTempTime = cd.add_constan_temp_time; Global::_currentCurveExperimentDataPtr->dataVtr.push_back(ed); - logde<<"111"; Global::_currentCurveExperimentDataPtr->curve = _currentCurve; - logde<<"222"; } #if 0 @@ -206,8 +206,6 @@ void CentralWidget::slotRecvAnalysisFileName(const QString &filePath) { qDebug() << "slotRecvAnalysisFileName" << filePath; - _customPlot->setInteractions(QCP::iSelectPlottables); - // todo.禁止重复文件添加。 Global::CurveFileData cfd; if(XlsxHandler::readFile(filePath,cfd) != 0){ @@ -343,7 +341,13 @@ void CentralWidget::slotAnalysisSettingApply() logde<<"lin1 x:"<<_line1->point1->coords().x(); - drawText(selectPoint,PointCalculate::textFormatNumbericalLabel(selectPoint)); + if(selectPoint.isNull()){ + QMessageBox::warning((QWidget*)this->parent(), "warnning", "曲线选择错误."); + return; + } + + drawText(selectPoint, + PointCalculate::textFormatNumbericalLabel(selectPoint)); break; } @@ -409,7 +413,8 @@ void CentralWidget::slotAnalysisSettingApply() void CentralWidget::slotAnalysisSettingConfirm() { slotAnalysisSettingApply(); - setAnalysisMode(CentralWidget::AnalysisMode::None); + + setAnalysisMode(CentralWidget::AnalysisMode::Null); _line1->setVisible(false); _line2->setVisible(false); @@ -425,7 +430,8 @@ void CentralWidget::slotAnalysisSettingUndo() void CentralWidget::slotAnalysisSettingCancel() { clearData(ClearDataMode::Undo); - setAnalysisMode(CentralWidget::AnalysisMode::None); + + setAnalysisMode(CentralWidget::AnalysisMode::Null); _line1->setVisible(false); _line2->setVisible(false); @@ -872,6 +878,7 @@ void CentralWidget::drawText(const QPointF point, const QString text) { QPointF textBoxPoint = getTheCoordinatesOfTheTextBox(point); + // 创建标注文字(QCPItemText) QCPItemText *textLabel = new QCPItemText(_customPlot); textLabel->setPositionAlignment(Qt::AlignBottom | Qt::AlignHCenter); // 对齐方式 diff --git a/src/ui/centralwidget.h b/src/ui/centralwidget.h index d389433..dfe14d2 100644 --- a/src/ui/centralwidget.h +++ b/src/ui/centralwidget.h @@ -16,7 +16,7 @@ class CentralWidget:public QWidget Q_OBJECT public: enum AnalysisMode{ - None, + Null, NumericalLabel, StartPoint, StopPoint, diff --git a/src/ui/experimentsettingform.cpp b/src/ui/experimentsettingform.cpp index f7fa538..eba777c 100644 --- a/src/ui/experimentsettingform.cpp +++ b/src/ui/experimentsettingform.cpp @@ -7,6 +7,7 @@ #include "serialport.h" #include "global.h" #include "filemanager.h" +#include "logger.h" QString extractObjectName(const QString& fullObjectName) { return fullObjectName.mid(4); // 去掉前 4 个字符("ui->") @@ -47,9 +48,8 @@ ExperimentSettingForm::~ExperimentSettingForm() void ExperimentSettingForm::uiReset() { // init data and status. - ui->checkBox_phase_1->setChecked(true); - ui->checkBox_phase_1->setEnabled(false); + // default value ui->phase_1_cutoff_temp->setText("0"); ui->phase_2_cutoff_temp->setText("0"); ui->phase_3_cutoff_temp->setText("0"); @@ -70,7 +70,18 @@ void ExperimentSettingForm::uiReset() ui->phase_4_constant_temp->setText("0"); ui->phase_5_constant_temp->setText("0"); ui->phase_6_constant_temp->setText("0"); - // + + ui->comboBox_phase_1_atmosphere->setCurrentIndex(0); + ui->comboBox_phase_2_atmosphere->setCurrentIndex(0); + ui->comboBox_phase_3_atmosphere->setCurrentIndex(0); + ui->comboBox_phase_4_atmosphere->setCurrentIndex(0); + ui->comboBox_phase_5_atmosphere->setCurrentIndex(0); + ui->comboBox_phase_6_atmosphere->setCurrentIndex(0); + + // default enable + ui->checkBox_phase_1->setChecked(true); + ui->checkBox_phase_1->setEnabled(false); + ui->phase_2_cutoff_temp->setEnabled(false); ui->phase_3_cutoff_temp->setEnabled(false); ui->phase_4_cutoff_temp->setEnabled(false); @@ -330,10 +341,9 @@ void ExperimentSettingForm::slotPhase6StateChanged(int state) void ExperimentSettingForm::on_pushButton_deliverData_clicked() { QVector phaseVtr; - if (ui->checkBox_phase_1->checkState()) { Phase phase; - phase.onoff = 1; + phase.onoff = ui->checkBox_phase_1->checkState()?1:0; phase.cutoff_temp = ui->phase_1_cutoff_temp->text().toFloat(); phase.temp_flow = ui->phase_1_scan_rate->text().toFloat(); phase.constant_temp_time_min = (uint16_t)ui->phase_1_constant_temp->text().toInt(); @@ -342,10 +352,9 @@ void ExperimentSettingForm::on_pushButton_deliverData_clicked() phaseVtr.push_back(phase); } - if (ui->checkBox_phase_2->checkState()) { Phase phase; - phase.onoff = 1; + phase.onoff = ui->checkBox_phase_2->checkState()?1:0; phase.cutoff_temp = ui->phase_2_cutoff_temp->text().toFloat(); phase.temp_flow = ui->phase_2_scan_rate->text().toFloat(); phase.constant_temp_time_min = (uint16_t)ui->phase_2_constant_temp->text().toInt(); @@ -355,10 +364,9 @@ void ExperimentSettingForm::on_pushButton_deliverData_clicked() phaseVtr.push_back(phase); } - if (ui->checkBox_phase_3->checkState()) { Phase phase; - phase.onoff = 1; + phase.onoff = ui->checkBox_phase_3->checkState()?1:0; phase.cutoff_temp = ui->phase_3_cutoff_temp->text().toFloat(); phase.temp_flow = ui->phase_3_scan_rate->text().toFloat(); phase.constant_temp_time_min = (uint16_t)ui->phase_3_constant_temp->text().toInt(); @@ -366,22 +374,21 @@ void ExperimentSettingForm::on_pushButton_deliverData_clicked() phaseVtr.push_back(phase); } - if (ui->checkBox_phase_4->checkState()) + { Phase phase; - phase.onoff = 1; + phase.onoff = ui->checkBox_phase_4->checkState()?1:0; phase.cutoff_temp = ui->phase_4_cutoff_temp->text().toFloat(); phase.temp_flow = ui->phase_4_scan_rate->text().toFloat(); phase.constant_temp_time_min = (uint16_t)ui->phase_4_constant_temp->text().toInt(); // phase.gas = ui->comboBox_phase_1_atmosphere->currentIndex(); phase.gas = GasType::N2; - phaseVtr.push_back(phase); } - if (ui->checkBox_phase_5->checkState()) + { Phase phase; - phase.onoff = 1; + phase.onoff = ui->checkBox_phase_5->checkState()?1:0; phase.cutoff_temp = ui->phase_5_cutoff_temp->text().toFloat(); phase.temp_flow = ui->phase_5_scan_rate->text().toFloat(); phase.constant_temp_time_min = (uint16_t)ui->phase_5_constant_temp->text().toInt(); @@ -390,10 +397,10 @@ void ExperimentSettingForm::on_pushButton_deliverData_clicked() phaseVtr.push_back(phase); } - if (ui->checkBox_phase_6->checkState()) + { Phase phase; - phase.onoff = 1; + phase.onoff = ui->checkBox_phase_6->checkState()?1:0; phase.cutoff_temp = ui->phase_6_cutoff_temp->text().toFloat(); phase.temp_flow = ui->phase_6_scan_rate->text().toFloat(); phase.constant_temp_time_min = (uint16_t)ui->phase_6_constant_temp->text().toInt(); @@ -486,20 +493,107 @@ void ExperimentSettingForm::slotPhaseCheck() void ExperimentSettingForm::slotRecvPhaseInfo(const QByteArray &ba) { + logde<<"-----------------------"; + QString hexData = ba.toHex(' '); // ' ' 作为分隔符,可选参数 + qDebug() << "slotRecvPhaseInfo hex:" << hexData; + QByteArray localba = ba; SerialPortProtocol *spp = (SerialPortProtocol *)localba.data(); u8 *data = spp->data_buf; + int phaseSize = spp->len / PHASE_BYTE_SIZE; + QVector phaseVtr; - for (int i = 0; i < 6; i++) + for (int i = 0; i < phaseSize; i++) { +#if 0 Phase *phase = (Phase *)(data + i * PHASE_BYTE_SIZE); phaseVtr.push_back(*phase); +#endif +#if 0 + u8* localData = data + i * PHASE_BYTE_SIZE; + int index = 0; + + Phase phase; + phase.onoff = *(localData + index); + index += 1; + + phase.cutoff_temp = (float)*(localData + index); + index += 4; + + phase.temp_flow = (float)*(localData + index); + index += 4; + + phase.constant_temp_time_min = (u16)*(localData + index); + index += 2; + + // phase.gas = (int)*(localData + index); + int gasType= (u8)*(localData + index); + + switch(gasType){ + case GasType::NC: + phase.gas = GasType::NC; + break; + case GasType::N2: + phase.gas = GasType::N2; + break; + case GasType::O2: + phase.gas = GasType::O2; + break; + default: + break; + } + + phaseVtr.push_back(phase); +#endif + uint8_t* localData = data + i * PHASE_BYTE_SIZE; + int index = 0; + + Phase phase; + // 解析 onoff + // phase.onoff = *(localData + index); + memcpy(&phase.onoff, localData + index, sizeof(uint8_t)); + index += sizeof(uint8_t); + + // 解析 cutoff_temp + memcpy(&phase.cutoff_temp, localData + index, sizeof(float)); + index += sizeof(float); + + // 解析 temp_flow + memcpy(&phase.temp_flow, localData + index, sizeof(float)); + index += sizeof(float); + + // 解析 constant_temp_time_min + memcpy(&phase.constant_temp_time_min, localData + index, sizeof(uint16_t)); + index += sizeof(uint16_t); + + // 解析 gas + uint8_t gasType = *(localData + index); + switch (gasType) { + case NC: + phase.gas = NC; + break; + case N2: + phase.gas = N2; + break; + case O2: + phase.gas = O2; + break; + default: + phase.gas = NC; // 默认值,表示未知类型 + break; + } + phaseVtr.push_back(phase); } + Global::_experimentInfo.phaseVtr = phaseVtr; //ui update +// logde<<"phaseVtr size:"<(this->findChild(checkBoxName)); if (checkBox_phase) { checkBox_phase->setChecked(true); - qDebug()<<"found..."; +// qDebug()<<"found..."; }else{ - qDebug()<<"not found..."; +// qDebug()<<"not found..."; } QString cutOffTempLineEditName = QString("phase_%1_cutoff_temp").arg(i); diff --git a/src/ui/leftwidget.h b/src/ui/leftwidget.h index 7603e21..cee0537 100644 --- a/src/ui/leftwidget.h +++ b/src/ui/leftwidget.h @@ -20,7 +20,6 @@ private: void initFileName(QTreeWidgetItem*,const QString &folderPath); void expandAll(QTreeWidgetItem* item); void clearAllChildItems(QTreeWidgetItem* parentItem); -protected: private slots: void slotTreeWidgetItemClicked(QTreeWidgetItem *item, int column); private: