From 29a746d8732f0cde3b070b26692b08f2fa05d518 Mon Sep 17 00:00:00 2001 From: anxinglong <2910824064@qq.com> Date: Wed, 22 Jul 2026 17:51:31 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E8=83=BD=E9=87=8F=E5=88=BB?= =?UTF-8?q?=E5=BA=A6=E7=AD=89=E8=A7=86=E5=9B=BE=E6=B2=A1=E6=9C=89=E5=8A=A0?= =?UTF-8?q?=E5=88=B0=E8=A7=86=E5=9B=BE=E8=8F=9C=E5=8D=95=E6=A0=8F=EF=BC=8C?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=8E=BB=E9=87=8D=E6=A0=B8=E7=B4=A0=E8=AF=86?= =?UTF-8?q?=E5=88=AB=E6=A1=86=E9=80=89=E5=90=8E=E8=AF=86=E5=88=AB=E7=9A=84?= =?UTF-8?q?=E6=A0=B8=E7=B4=A0=E4=BF=A1=E6=81=AF=E6=B7=BB=E5=8A=A0=E5=88=B0?= =?UTF-8?q?=E6=A0=B8=E7=B4=A0=E8=AF=86=E5=88=AB=E7=9A=84=E9=80=89=E6=8B=A9?= =?UTF-8?q?=E5=BC=B9=E6=A1=86=EF=BC=8C=E4=BF=AE=E6=94=B9=E6=A0=B8=E7=B4=A0?= =?UTF-8?q?=E8=AF=86=E5=88=AB=E7=9A=84=E9=80=89=E6=8B=A9=E5=BC=B9=E6=A1=86?= =?UTF-8?q?=E7=9A=84=E5=90=8D=E7=A7=B0=E2=80=9C=E5=8C=B9=E9=85=8D=E6=A0=B8?= =?UTF-8?q?=E7=B4=A0=E5=B0=84=E7=BA=BF=E2=80=9D=E4=B8=BA=E2=80=9C=E6=A0=B8?= =?UTF-8?q?=E7=B4=A0=E8=AF=86=E5=88=AB=E2=80=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../TwoDSpectralCompliance.cpp | 1 + .../NuclideAnalysisView.cpp | 129 ++++++++++++------ src/NuclideAnalysisView/NuclideAnalysisView.h | 4 + .../ConformityAnalysis.cpp | 2 +- 4 files changed, 96 insertions(+), 40 deletions(-) diff --git a/src/2DSpectralCompliance/TwoDSpectralCompliance.cpp b/src/2DSpectralCompliance/TwoDSpectralCompliance.cpp index 0e8b0cd..c40c28e 100644 --- a/src/2DSpectralCompliance/TwoDSpectralCompliance.cpp +++ b/src/2DSpectralCompliance/TwoDSpectralCompliance.cpp @@ -55,6 +55,7 @@ TwoDSpectralCompliance::TwoDSpectralCompliance(QWidget* parent) , ui(new Ui::TwoDSpectralCompliance) { ui->setupUi(this); + this->setViewType(PlotFrame); this->_menu = new QMenu(this); setupMenu(); QHBoxLayout* layout = new QHBoxLayout(this); diff --git a/src/NuclideAnalysisView/NuclideAnalysisView.cpp b/src/NuclideAnalysisView/NuclideAnalysisView.cpp index 0a1e9f7..f5de4d0 100644 --- a/src/NuclideAnalysisView/NuclideAnalysisView.cpp +++ b/src/NuclideAnalysisView/NuclideAnalysisView.cpp @@ -100,7 +100,6 @@ void NuclideAnalysisView::SetAnalyzeDataFilename(const QMap& const QString& data_filename = data_files_set.first().toString(); if (QFileInfo(data_filename).exists()) { loadDataFromFile(data_name, data_filename); - } } @@ -223,6 +222,11 @@ void NuclideAnalysisView::setupMenu() connect(action_plot_clear, &QAction::triggered, this, &NuclideAnalysisView::onActionPlotClear); this->_menu->addSeparator(); + QAction* action_plot_nuclide_recognition = this->_menu->addAction(QStringLiteral(u"核素识别")); + action_plot_nuclide_recognition->setObjectName("action_plot_nuclide_recognition"); + connect(action_plot_nuclide_recognition, &QAction::triggered, this, &NuclideAnalysisView::onActionPlotNuclideRecognition); + this->_menu->addSeparator(); + setupNuclideDialog(); } @@ -328,6 +332,10 @@ void NuclideAnalysisView::onActionPlotClear() _plot->replot(); } +void NuclideAnalysisView::onActionPlotNuclideRecognition() +{ + m_nuclideDialog->show(); +} void NuclideAnalysisView::addVerticalLine(double xValue, const QColor& color) { @@ -646,7 +654,7 @@ std::vector NuclideAnalysisView::GetSvdPeaks(const QVe void NuclideAnalysisView::setupNuclideDialog() { m_nuclideDialog = new QDialog(this); - m_nuclideDialog->setWindowTitle(QStringLiteral(u"匹配核素射线")); + m_nuclideDialog->setWindowTitle(QStringLiteral(u"核素识别")); m_nuclideDialog->resize(700, 400); QVBoxLayout* layout = new QVBoxLayout(m_nuclideDialog); @@ -665,18 +673,20 @@ void NuclideAnalysisView::setupNuclideDialog() layout->addLayout(topBarLayout); m_nuclideTable = new QTableWidget(m_nuclideDialog); - QStringList headers = { "核素", "射线类型", "能量(keV)", "操作" }; + QStringList headers = {"选择", "核素", "射线类型", "能量(keV)", "操作" }; m_nuclideTable->setColumnCount(headers.size()); m_nuclideTable->setHorizontalHeaderLabels(headers); m_nuclideTable->setSelectionBehavior(QAbstractItemView::SelectRows); m_nuclideTable->setEditTriggers(QAbstractItemView::NoEditTriggers); m_nuclideTable->setAlternatingRowColors(true); - m_nuclideTable->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch); + m_nuclideTable->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Fixed); + m_nuclideTable->setColumnWidth(0, 60); m_nuclideTable->horizontalHeader()->setSectionResizeMode(1, QHeaderView::Stretch); m_nuclideTable->horizontalHeader()->setSectionResizeMode(2, QHeaderView::Stretch); - m_nuclideTable->horizontalHeader()->setSectionResizeMode(3, QHeaderView::Fixed); - m_nuclideTable->setColumnWidth(3, 120); + m_nuclideTable->horizontalHeader()->setSectionResizeMode(3, QHeaderView::Stretch); + m_nuclideTable->horizontalHeader()->setSectionResizeMode(4, QHeaderView::Fixed); + m_nuclideTable->setColumnWidth(4, 80); layout->addWidget(m_nuclideTable); connect(m_nuclideTable, &QTableWidget::itemSelectionChanged, this, &NuclideAnalysisView::onNuclideTableSelectionChanged); @@ -696,7 +706,7 @@ void NuclideAnalysisView::queryNuclidesForPeak(const PeakFitResultNuclide& peak) if (!openNuclideDatabase()) { m_nuclideTable->setRowCount(1); - m_nuclideTable->setItem(0, 0, new QTableWidgetItem(QStringLiteral(u"数据库未打开"))); + m_nuclideTable->setItem(0, 1, new QTableWidgetItem(QStringLiteral(u"数据库未打开"))); m_nuclideDialog->show(); return; } @@ -799,7 +809,7 @@ void NuclideAnalysisView::queryNuclidesForPeak(const PeakFitResultNuclide& peak) //多峰显示 if (m_nuclideTable->rowCount() > 0) { - QTableWidgetItem* firstItem = m_nuclideTable->item(0, 0); + QTableWidgetItem* firstItem = m_nuclideTable->item(0, 1); if (firstItem) { QString txt = firstItem->text(); if (txt == QStringLiteral(u"未找到匹配核素") || @@ -809,22 +819,24 @@ void NuclideAnalysisView::queryNuclidesForPeak(const PeakFitResultNuclide& peak) } } - // 新匹配结果追加到表格末尾 - int startRow = m_nuclideTable->rowCount(); for (int i = 0; i < matches.size(); ++i) { - int row = startRow + i; + const auto& matchItem = matches[i]; + // 已存在相同核素+射线类型+能量则跳过 + if (isNuclideExists(matchItem.nuclideName, matchItem.rayType, matchItem.energyDisplay)) { + continue; + } + int row = m_nuclideTable->rowCount(); m_nuclideTable->insertRow(row); - const auto& m = matches[i]; - m_nuclideTable->setItem(row, 0, new QTableWidgetItem(m.nuclideName)); - m_nuclideTable->setItem(row, 1, new QTableWidgetItem(m.rayType)); - m_nuclideTable->setItem(row, 2, new QTableWidgetItem(m.energyDisplay)); + m_nuclideTable->setItem(row, 1, new QTableWidgetItem(matchItem.nuclideName)); + m_nuclideTable->setItem(row, 2, new QTableWidgetItem(matchItem.rayType)); + m_nuclideTable->setItem(row, 3, new QTableWidgetItem(matchItem.energyDisplay)); createRowOperationWidgets(row); } // 表格为空且没匹配到时,才显示提示 if (m_nuclideTable->rowCount() == 0 && matches.isEmpty()) { m_nuclideTable->setRowCount(1); - m_nuclideTable->setItem(0, 0, new QTableWidgetItem(QStringLiteral(u"未找到匹配核素"))); + m_nuclideTable->setItem(0, 1, new QTableWidgetItem(QStringLiteral(u"未找到匹配核素"))); } m_nuclideDialog->show(); @@ -849,25 +861,29 @@ bool NuclideAnalysisView::openNuclideDatabase() void NuclideAnalysisView::createRowOperationWidgets(int row) { - QWidget* operationWidget = new QWidget(m_nuclideTable); - QHBoxLayout* hLayout = new QHBoxLayout(operationWidget); - hLayout->setContentsMargins(4, 2, 4, 2); - hLayout->setSpacing(8); - - // 复选框 - QCheckBox* checkBox = new QCheckBox(operationWidget); + QWidget* checkWidget = new QWidget(m_nuclideTable); + QHBoxLayout* checkLayout = new QHBoxLayout(checkWidget); + checkLayout->setContentsMargins(2,0,2,0); + checkLayout->setSpacing(0); + QCheckBox* checkBox = new QCheckBox(checkWidget); checkBox->setObjectName("rowCheckBox"); - hLayout->addWidget(checkBox); - hLayout->addStretch(); + checkLayout->addStretch(); + checkLayout->addWidget(checkBox); + checkLayout->addStretch(); + m_nuclideTable->setCellWidget(row, 0, checkWidget); - // 删除按钮 - QPushButton* deleteBtn = new QPushButton(QStringLiteral(u"删除"), operationWidget); + QWidget* delWidget = new QWidget(m_nuclideTable); + QHBoxLayout* delLayout = new QHBoxLayout(delWidget); + delLayout->setContentsMargins(2,0,2,0); + delLayout->setSpacing(0); + QPushButton* deleteBtn = new QPushButton(QStringLiteral(u"删除"), delWidget); deleteBtn->setFixedWidth(50); deleteBtn->setProperty("rowIndex", row); connect(deleteBtn, &QPushButton::clicked, this, &NuclideAnalysisView::onDeleteRow); - hLayout->addWidget(deleteBtn); - - m_nuclideTable->setCellWidget(row, 3, operationWidget); + delLayout->addStretch(); + delLayout->addWidget(deleteBtn); + delLayout->addStretch(); + m_nuclideTable->setCellWidget(row, 4, delWidget); } void NuclideAnalysisView::onDeleteRow() @@ -880,7 +896,7 @@ void NuclideAnalysisView::onDeleteRow() m_nuclideTable->removeRow(row); // 更新后续行的rowIndex属性 for (int i = row; i < m_nuclideTable->rowCount(); ++i) { - QWidget* widget = m_nuclideTable->cellWidget(i, 3); + QWidget* widget = m_nuclideTable->cellWidget(i, 4); if (widget) { QPushButton* delBtn = widget->findChild(); if (delBtn) { @@ -896,13 +912,13 @@ void NuclideAnalysisView::onSaveSelectedNuclides() QJsonArray nuclideArray; for (int i = 0; i < m_nuclideTable->rowCount(); ++i) { - QWidget* widget = m_nuclideTable->cellWidget(i, 3); + QWidget* widget = m_nuclideTable->cellWidget(i, 0); if (widget) { QCheckBox* checkBox = widget->findChild(); if (checkBox && checkBox->isChecked()) { - QTableWidgetItem* nuclideItem = m_nuclideTable->item(i, 0); - QTableWidgetItem* rayTypeItem = m_nuclideTable->item(i, 1); - QTableWidgetItem* energyItem = m_nuclideTable->item(i, 2); + QTableWidgetItem* nuclideItem = m_nuclideTable->item(i, 1); + QTableWidgetItem* rayTypeItem = m_nuclideTable->item(i, 2); + QTableWidgetItem* energyItem = m_nuclideTable->item(i, 3); if (nuclideItem) { QJsonObject obj; @@ -946,11 +962,16 @@ void NuclideAnalysisView::onAddNuclide() if (ray.size() >= 3) { QString nuclideName = ray.at(1); QString energy = ray.at(2); + const QString rayType = QStringLiteral(u"γ"); // 手动添加默认为γ射线 + // 已存在相同核素则跳过 + if (isNuclideExists(nuclideName, rayType, energy)) { + continue; + } int row = m_nuclideTable->rowCount(); m_nuclideTable->insertRow(row); - m_nuclideTable->setItem(row, 0, new QTableWidgetItem(nuclideName)); - m_nuclideTable->setItem(row, 1, new QTableWidgetItem(QStringLiteral(u"γ"))); - m_nuclideTable->setItem(row, 2, new QTableWidgetItem(energy)); + m_nuclideTable->setItem(row, 1, new QTableWidgetItem(nuclideName)); + m_nuclideTable->setItem(row, 2, new QTableWidgetItem(QStringLiteral(u"γ"))); + m_nuclideTable->setItem(row, 3, new QTableWidgetItem(energy)); createRowOperationWidgets(row); } } @@ -978,7 +999,7 @@ void NuclideAnalysisView::onNuclideTableSelectionChanged() // 遍历选中行,解析能量画竖线 for (const QTableWidgetSelectionRange& range : ranges) { for (int row = range.topRow(); row <= range.bottomRow(); ++row) { - QTableWidgetItem* item = m_nuclideTable->item(row, 2); + QTableWidgetItem* item = m_nuclideTable->item(row, 3); if (!item) continue; QString str = item->text().trimmed(); @@ -1013,4 +1034,34 @@ void NuclideAnalysisView::addNuclideVLine(double energy) marker->setValue(energy, 0); marker->attach(_plot); m_selectedNuclideMarkers.append(marker); +} + +bool NuclideAnalysisView::isNuclideExists(const QString &nuclideName, const QString &rayType, const QString &energy) +{ + const QString trimmedName = nuclideName.trimmed(); + const QString trimmedType = rayType.trimmed(); + const QString trimmedEnergy = energy.trimmed(); + + for (int i = 0; i < m_nuclideTable->rowCount(); ++i) { + QTableWidgetItem* nameItem = m_nuclideTable->item(i, 1); + QTableWidgetItem* typeItem = m_nuclideTable->item(i, 2); + QTableWidgetItem* energyItem = m_nuclideTable->item(i, 3); + + // 跳过空行或提示行("未找到匹配核素"、"数据库未打开") + if (!nameItem) continue; + const QString firstColText = nameItem->text().trimmed(); + if (firstColText == QStringLiteral(u"未找到匹配核素") || + firstColText == QStringLiteral(u"数据库未打开")) { + continue; + } + + // 三字段完全匹配(忽略前后空格)则判定为重复 + if (nameItem && typeItem && energyItem && + nameItem->text().trimmed() == trimmedName && + typeItem->text().trimmed() == trimmedType && + energyItem->text().trimmed() == trimmedEnergy) { + return true; + } + } + return false; } \ No newline at end of file diff --git a/src/NuclideAnalysisView/NuclideAnalysisView.h b/src/NuclideAnalysisView/NuclideAnalysisView.h index a6ae4dc..e85bc35 100644 --- a/src/NuclideAnalysisView/NuclideAnalysisView.h +++ b/src/NuclideAnalysisView/NuclideAnalysisView.h @@ -83,6 +83,8 @@ private: void createRowOperationWidgets(int row); void addNuclideVLine(double energy); + // 判断表格中是否已存在相同核素 + bool isNuclideExists(const QString& nuclideName, const QString& rayType, const QString& energy); private slots: void onActionPlotConfigure(); @@ -92,6 +94,8 @@ private slots: void onActionPlotClear(); + //核素识别 + void onActionPlotNuclideRecognition(); void onDeleteRow(); void onSaveSelectedNuclides(); diff --git a/src/ThreeDimensionalConformityAnalysisView/ConformityAnalysis.cpp b/src/ThreeDimensionalConformityAnalysisView/ConformityAnalysis.cpp index f19f068..aeae656 100644 --- a/src/ThreeDimensionalConformityAnalysisView/ConformityAnalysis.cpp +++ b/src/ThreeDimensionalConformityAnalysisView/ConformityAnalysis.cpp @@ -166,7 +166,7 @@ ConformityAnalysis::ConformityAnalysis(QWidget *parent) : { qRegisterMetaType(); qRegisterMetaType(); - + this->setViewType(PlotFrame); ui->setupUi(this); memset(m_boardChannel, 0, sizeof(m_boardChannel));