新增界面选择核素界面。添加点击核素,在视图上显示竖线

This commit is contained in:
anxinglong 2026-06-24 17:53:41 +08:00
parent 1c6bd01ed6
commit 2e4d09a03e
6 changed files with 888 additions and 18 deletions

View File

@ -0,0 +1,263 @@
#include "AddNuclideDialog.h"
#include "ui_AddNuclideDialog.h"
#include "sqlitemanager.h"
#include <QCheckBox>
#include <QHBoxLayout>
#include <QHeaderView>
AddNuclideDialog::AddNuclideDialog(QWidget *parent)
: QDialog(parent)
, ui(new Ui::AddNuclideDialog)
{
ui->setupUi(this);
setWindowTitle(QStringLiteral(u"新增核素"));
this->initTable(ui->tableWidget_left);
connect(ui->tableWidget_left, &QTableWidget::itemClicked, this, &AddNuclideDialog::slotTableItemClicked);
this->initTable(ui->tableWidget_cter);
this->initTable(ui->tableWidget_right);
this->initHeaderItem(ui->tableWidget_cter, { QStringLiteral(u"编号"), QStringLiteral(u"能量KeV"), QStringLiteral(u"发射几率%"), QStringLiteral(u"操作") });
this->initHeaderItem(ui->tableWidget_right, { QStringLiteral(u"核素"), QStringLiteral(u"能量KeV") });
connect(ui->lineEdit_up, &QLineEdit::textChanged, this, &AddNuclideDialog::onSearchTextChanged);
this->readNuclideData();
}
AddNuclideDialog::~AddNuclideDialog()
{
delete ui;
}
void AddNuclideDialog::readNuclideData()
{
auto& db = SqliteManager::instance();
QString sql = "SELECT ID, NUCLIDE_NAME FROM nuclideLib ORDER BY NUCLIDE_NAME;";
auto nuclideList = db.selectRows(sql);
m_allNuclideList.clear();
for (const auto& row : nuclideList) {
QString id = row["ID"].toString();
QString name = row["NUCLIDE_NAME"].toString();
QStringList slist;
slist << id;
slist << name;
m_allNuclideList.append(slist);
this->insertTableWidget(ui->tableWidget_left, slist);
}
}
void AddNuclideDialog::initTable(QTableWidget* tableWgt)
{
tableWgt->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
tableWgt->setSelectionBehavior(QAbstractItemView::SelectRows);
tableWgt->setFocusPolicy(Qt::NoFocus);
tableWgt->setShowGrid(false);
tableWgt->setAlternatingRowColors(true);
}
void AddNuclideDialog::initHeaderItem(QTableWidget* tableWgt, QStringList hlist, bool bvis)
{
tableWgt->setColumnCount(0);
tableWgt->setRowCount(0);
int ncolCount = 0;
for (int i = 0; i < hlist.length(); i++) {
tableWgt->insertColumn(ncolCount);
tableWgt->setHorizontalHeaderItem(ncolCount, new QTableWidgetItem(hlist.at(i)));
ncolCount = tableWgt->columnCount();
}
tableWgt->horizontalHeader()->setVisible(bvis);
}
void AddNuclideDialog::insertTableWidget(QTableWidget* tableWidget, QStringList listDt)
{
int rowCount = tableWidget->rowCount();
tableWidget->insertRow(rowCount);
int nIdx = 0;
for (int i = 1; i < listDt.size(); i++) {
QString str = listDt[i];
if (nIdx >= tableWidget->columnCount())
break;
QTableWidgetItem* pItem = new QTableWidgetItem(str);
if (nIdx == 0) {
pItem->setData(Qt::UserRole, listDt[0]);
}
pItem->setTextAlignment(Qt::AlignCenter);
pItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
tableWidget->setItem(rowCount, nIdx, pItem);
tableWidget->setRowHeight(rowCount, 30);
nIdx++;
}
if (tableWidget == ui->tableWidget_cter) {
nIdx = tableWidget->columnCount() - 1;
QWidget* operatorWidget = new QWidget(tableWidget);
QHBoxLayout* layout = new QHBoxLayout(operatorWidget);
layout->setContentsMargins(2, 0, 2, 0);
layout->setSpacing(10);
QCheckBox* box = new QCheckBox(operatorWidget);
if (this->hvNuclideRay(listDt[0]))
box->setChecked(true);
else
box->setChecked(false);
box->setProperty("id", listDt[0]);
connect(box, &QCheckBox::stateChanged, this, &AddNuclideDialog::on_checkChanged);
layout->addStretch();
layout->addWidget(box);
layout->addStretch();
tableWidget->setCellWidget(rowCount, nIdx, operatorWidget);
}
}
QList<QStringList>& AddNuclideDialog::getSelectRay()
{
return m_listSelectRay;
}
QString AddNuclideDialog::getSelectRayMev(QString sid)
{
QString str;
for (int i = 0; i < m_listCurNuclideRayInfo.size(); i++) {
if (m_listCurNuclideRayInfo.at(i).at(0) == sid) {
str = m_listCurNuclideRayInfo.at(i).at(3);
break;
}
}
return str;
}
void AddNuclideDialog::removeSelectRay(QString sid)
{
for (int i = 0; i < m_listSelectRay.size(); i++) {
if (m_listSelectRay.at(i).at(0) == sid) {
m_listSelectRay.removeAt(i);
break;
}
}
}
bool AddNuclideDialog::hvNuclideRay(QString sid)
{
for (int i = 0; i < m_listSelectRay.size(); i++) {
if (m_listSelectRay.at(i).at(0) == sid) {
return true;
}
}
return false;
}
void AddNuclideDialog::on_checkChanged()
{
QCheckBox* cb = qobject_cast<QCheckBox*>(sender());
QString sid = cb->property("id").toString();
if (cb->isChecked()) {
QString smev = this->getSelectRayMev(sid);
QStringList slt;
slt << sid;
slt << m_strNucName;
slt << smev;
m_listSelectRay << slt;
} else {
this->removeSelectRay(sid);
}
ui->tableWidget_right->setRowCount(0);
for (int i = 0; i < m_listSelectRay.size(); i++) {
QStringList slit = m_listSelectRay.at(i);
this->insertTableWidget(ui->tableWidget_right, slit);
}
}
void AddNuclideDialog::slotTableItemClicked(QTableWidgetItem* item)
{
if (item == nullptr)
return;
QString sid = item->data(Qt::UserRole).toString();
m_strNucName = item->text();
auto& db = SqliteManager::instance();
// 查询核素基本信息(半衰期等)
QString nuclideSql = QString("SELECT * FROM nuclideLib WHERE ID = %1;").arg(sid);
auto nuclideInfo = db.selectRows(nuclideSql);
if (!nuclideInfo.isEmpty()) {
auto& firstRow = nuclideInfo.first();
if (firstRow.contains("HALF_LIFE")) {
ui->lineEdit_halfleft->setText(firstRow["HALF_LIFE"].toString());
}
// 半衰期不确定度
if (firstRow.contains("HALF_LIFE_UNCERTAINTY")) {
ui->lineEdit_halfleftun->setText(firstRow["HALF_LIFE_UNCERTAINTY"].toString());
} else if (firstRow.contains("HALF_LIFE_UNC")) {
ui->lineEdit_halfleftun->setText(firstRow["HALF_LIFE_UNC"].toString());
} else if (firstRow.contains("HALF_LIFE_ERROR")) {
ui->lineEdit_halfleftun->setText(firstRow["HALF_LIFE_ERROR"].toString());
}
}
ui->label_c1->setText(QStringLiteral(u"核素信息 %1").arg(m_strNucName));
ui->tableWidget_cter->setRowCount(0);
// 查询核素射线信息
QString raySql = QString("SELECT ID, NUCLIDE_ID, RAY_TYPE, RAY_MEV, RAY_BRANCH_RATIO "
"FROM nuclideRayInfo WHERE NUCLIDE_ID = %1;").arg(sid);
auto rayInfoList = db.selectRows(raySql);
m_listCurNuclideRayInfo.clear();
for (int i = 0; i < rayInfoList.size(); i++) {
const auto& row = rayInfoList.at(i);
QStringList slt;
slt << row["ID"].toString();
slt << row["NUCLIDE_ID"].toString();
slt << row["RAY_TYPE"].toString();
slt << row["RAY_MEV"].toString();
slt << row["RAY_BRANCH_RATIO"].toString();
m_listCurNuclideRayInfo.append(slt);
QStringList tmp;
tmp << row["ID"].toString();
tmp << QString::number(i + 1);
tmp << row["RAY_MEV"].toString();
tmp << row["RAY_BRANCH_RATIO"].toString();
this->insertTableWidget(ui->tableWidget_cter, tmp);
}
}
void AddNuclideDialog::on_btn_ok_clicked()
{
this->accept();
}
void AddNuclideDialog::on_btn_cancle_clicked()
{
this->reject();
}
void AddNuclideDialog::onSearchTextChanged(const QString &text)
{
ui->tableWidget_left->setRowCount(0);
QString searchText = text.trimmed();
if (searchText.isEmpty()) {
// 搜索框为空,显示所有核素
for (const QStringList& nuclide : m_allNuclideList) {
this->insertTableWidget(ui->tableWidget_left, nuclide);
}
return;
}
// 模糊搜索,不区分大小写
for (const QStringList& nuclide : m_allNuclideList) {
QString name = nuclide.at(1);
if (name.contains(searchText, Qt::CaseInsensitive)) {
this->insertTableWidget(ui->tableWidget_left, nuclide);
}
}
}

View File

@ -0,0 +1,49 @@
#ifndef ADDNUCLIDEDIALOG_H
#define ADDNUCLIDEDIALOG_H
#include <QDialog>
#include <QTableWidget>
#include <QList>
#include <QStringList>
namespace Ui {
class AddNuclideDialog;
}
class AddNuclideDialog : public QDialog
{
Q_OBJECT
public:
explicit AddNuclideDialog(QWidget *parent = nullptr);
~AddNuclideDialog();
void readNuclideData();
void initTable(QTableWidget* tableWgt);
void initHeaderItem(QTableWidget* tableWgt, QStringList hlist, bool bvis = true);
void insertTableWidget(QTableWidget* tableWidget, QStringList vecList);
QList<QStringList>& getSelectRay();
protected:
QString getSelectRayMev(QString sid);
void removeSelectRay(QString sid);
bool hvNuclideRay(QString sid);
private slots:
void on_checkChanged();
void slotTableItemClicked(QTableWidgetItem* item);
void on_btn_ok_clicked();
void on_btn_cancle_clicked();
void onSearchTextChanged(const QString& text);
private:
Ui::AddNuclideDialog *ui;
QString m_strNucName;
QList<QStringList> m_listCurNuclideRayInfo;
QList<QStringList> m_listSelectRay;
QList<QStringList> m_allNuclideList; // 所有核素数据(用于搜索过滤)
};
#endif // ADDNUCLIDEDIALOG_H

View File

@ -0,0 +1,375 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>AddNuclideDialog</class>
<widget class="QDialog" name="AddNuclideDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1097</width>
<height>579</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout" stretch="20,1">
<item>
<layout class="QHBoxLayout" name="horizontalLayout" stretch="1,2,1">
<item>
<widget class="QWidget" name="widget_1" native="true">
<property name="styleSheet">
<string notr="true"/>
</property>
<layout class="QVBoxLayout" name="verticalLayout_5">
<property name="leftMargin">
<number>1</number>
</property>
<property name="topMargin">
<number>1</number>
</property>
<property name="rightMargin">
<number>1</number>
</property>
<property name="bottomMargin">
<number>1</number>
</property>
<item>
<layout class="QVBoxLayout" name="verticalLayout_4">
<property name="spacing">
<number>6</number>
</property>
<property name="leftMargin">
<number>9</number>
</property>
<property name="topMargin">
<number>9</number>
</property>
<property name="rightMargin">
<number>9</number>
</property>
<property name="bottomMargin">
<number>9</number>
</property>
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>核素搜索:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineEdit_up"/>
</item>
</layout>
</item>
<item>
<widget class="QTableWidget" name="tableWidget_left">
<property name="maximumSize">
<size>
<width>16777215</width>
<height>16777215</height>
</size>
</property>
<attribute name="horizontalHeaderVisible">
<bool>true</bool>
</attribute>
<attribute name="verticalHeaderVisible">
<bool>false</bool>
</attribute>
<column>
<property name="text">
<string>核素</string>
</property>
</column>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QWidget" name="widget_2" native="true">
<property name="styleSheet">
<string notr="true">QWidget#widget_plot{
border: 1px solid #2c5f8c;
}</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_6">
<property name="leftMargin">
<number>1</number>
</property>
<property name="topMargin">
<number>1</number>
</property>
<property name="rightMargin">
<number>1</number>
</property>
<property name="bottomMargin">
<number>1</number>
</property>
<item>
<layout class="QVBoxLayout" name="verticalLayout_7">
<property name="spacing">
<number>6</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="label_c1">
<property name="styleSheet">
<string notr="true"/>
</property>
<property name="text">
<string>核素信息 </string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<layout class="QGridLayout" name="gridLayout">
<property name="leftMargin">
<number>80</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>80</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item row="0" column="1">
<widget class="QLineEdit" name="lineEdit_halfleft"/>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>半衰期:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_7">
<property name="text">
<string>核素不确定度:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="lineEdit_halfleftun"/>
</item>
</layout>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_8">
<property name="spacing">
<number>1</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="label_c2">
<property name="styleSheet">
<string notr="true"/>
</property>
<property name="text">
<string>峰信息 </string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QTableWidget" name="tableWidget_cter">
<property name="maximumSize">
<size>
<width>16777215</width>
<height>16777215</height>
</size>
</property>
<attribute name="horizontalHeaderVisible">
<bool>true</bool>
</attribute>
<attribute name="verticalHeaderVisible">
<bool>false</bool>
</attribute>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_11">
<property name="spacing">
<number>1</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="label_c3">
<property name="styleSheet">
<string notr="true"/>
</property>
<property name="text">
<string>能量刻度-核素以能量</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QTableWidget" name="tableWidget_right">
<property name="maximumSize">
<size>
<width>16777215</width>
<height>16777215</height>
</size>
</property>
<attribute name="horizontalHeaderVisible">
<bool>true</bool>
</attribute>
<attribute name="verticalHeaderVisible">
<bool>false</bool>
</attribute>
</widget>
</item>
</layout>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="btn_ok">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>30</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>90</width>
<height>16777215</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">QPushButton{
background-color: #1d7be0;
border: 0px solid #1A8EE5;
padding-left:13px;
padding-right:13px;
font-size: 15px;
font-family: Microsoft YaHei;
color:#ffffff;
}
QPushButton:pressed{
background-color: #11c678;
}
QPushButton:hover{
background-color: #1e80e8;
}
QPushButton::menu-indicator {
subcontrol-position: right center;
}</string>
</property>
<property name="text">
<string>确定</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btn_cancle">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>90</width>
<height>16777215</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">QPushButton{
background-color: #738087;
border: 0px solid #1A8EE5;
padding-left:13px;
padding-right:13px;
font-size: 15px;
font-family: Microsoft YaHei;
color:#ffffff;
}
QPushButton:pressed{
background-color: #11c678;
}
QPushButton:hover{
background-color: #87979f;
}
QPushButton::menu-indicator {
subcontrol-position: right center;
}</string>
</property>
<property name="text">
<string>取消</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -10,7 +10,12 @@
#include <QwtPlotCanvas> #include <QwtPlotCanvas>
#include <QwtText> #include <QwtText>
#include <QPen> #include <QPen>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include <QMessageBox>
#include <QHeaderView>
#include "AddNuclideDialog.h"
// 更新选择框显示 // 更新选择框显示
static void updateSelectionMarkers(QwtPlot* plot, static void updateSelectionMarkers(QwtPlot* plot,
QwtPlotMarker*& leftMarker, QwtPlotMarker*& leftMarker,
@ -209,10 +214,10 @@ void NuclideAnalysisView::setupMenu()
connect(action_plot_config, &QAction::triggered, this, &NuclideAnalysisView::onActionPlotConfigure); connect(action_plot_config, &QAction::triggered, this, &NuclideAnalysisView::onActionPlotConfigure);
this->_menu->addSeparator(); this->_menu->addSeparator();
QAction* action_plot_select = this->_menu->addAction(QStringLiteral(u"在谱线上选择")); // QAction* action_plot_select = this->_menu->addAction(QStringLiteral(u"在谱线上选择"));
action_plot_select->setObjectName("plot_select"); // action_plot_select->setObjectName("plot_select");
connect(action_plot_select, &QAction::triggered, this, &NuclideAnalysisView::onActionPlotSelect); // connect(action_plot_select, &QAction::triggered, this, &NuclideAnalysisView::onActionPlotSelect);
this->_menu->addSeparator(); // this->_menu->addSeparator();
QAction* action_plot_clear = this->_menu->addAction(QStringLiteral(u"清除")); QAction* action_plot_clear = this->_menu->addAction(QStringLiteral(u"清除"));
action_plot_clear->setObjectName("plot_clear"); action_plot_clear->setObjectName("plot_clear");
@ -306,6 +311,14 @@ void NuclideAnalysisView::onActionPlotClear()
m_selectRightMarker = nullptr; m_selectRightMarker = nullptr;
} }
for (QwtPlotMarker* marker : m_selectedNuclideMarkers) {
if (marker) {
marker->detach();
delete marker;
}
}
m_selectedNuclideMarkers.clear();
m_allFitResults.clear(); m_allFitResults.clear();
m_bSelecting = false; m_bSelecting = false;
@ -542,7 +555,7 @@ void NuclideAnalysisView::DrawPeaks(const QVector<PeakFitResultNuclide>& peaks)
QwtPlotCurve* rectCurve = new QwtPlotCurve(); QwtPlotCurve* rectCurve = new QwtPlotCurve();
rectCurve->setSamples(rectPoints); rectCurve->setSamples(rectPoints);
rectCurve->setPen(QPen(color, 2, Qt::SolidLine)); rectCurve->setPen(QPen(color, 1, Qt::SolidLine));
rectCurve->setBrush(QBrush(fillColor)); rectCurve->setBrush(QBrush(fillColor));
rectCurve->attach(_plot); rectCurve->attach(_plot);
m_peakMarkers.append(static_cast<QwtPlotItem*>(rectCurve)); m_peakMarkers.append(static_cast<QwtPlotItem*>(rectCurve));
@ -633,7 +646,7 @@ void NuclideAnalysisView::setupNuclideDialog()
{ {
m_nuclideDialog = new QDialog(this); m_nuclideDialog = new QDialog(this);
m_nuclideDialog->setWindowTitle(QStringLiteral(u"匹配核素射线")); m_nuclideDialog->setWindowTitle(QStringLiteral(u"匹配核素射线"));
m_nuclideDialog->resize(520, 400); m_nuclideDialog->resize(700, 400);
QVBoxLayout* layout = new QVBoxLayout(m_nuclideDialog); QVBoxLayout* layout = new QVBoxLayout(m_nuclideDialog);
layout->setContentsMargins(6, 6, 6, 6); layout->setContentsMargins(6, 6, 6, 6);
@ -651,18 +664,33 @@ void NuclideAnalysisView::setupNuclideDialog()
layout->addLayout(topBarLayout); layout->addLayout(topBarLayout);
m_nuclideTable = new QTableWidget(m_nuclideDialog); m_nuclideTable = new QTableWidget(m_nuclideDialog);
QStringList headers = { "核素", "射线类型", "能量(keV)","操作" }; QStringList headers = { "核素", "射线类型", "能量(keV)", "操作" };
m_nuclideTable->setColumnCount(headers.size()); m_nuclideTable->setColumnCount(headers.size());
m_nuclideTable->setHorizontalHeaderLabels(headers); m_nuclideTable->setHorizontalHeaderLabels(headers);
// m_nuclideTable->horizontalHeader()->setStretchLastSection(true);
m_nuclideTable->setSelectionBehavior(QAbstractItemView::SelectRows); m_nuclideTable->setSelectionBehavior(QAbstractItemView::SelectRows);
m_nuclideTable->setEditTriggers(QAbstractItemView::NoEditTriggers); m_nuclideTable->setEditTriggers(QAbstractItemView::NoEditTriggers);
m_nuclideTable->setAlternatingRowColors(true); m_nuclideTable->setAlternatingRowColors(true);
m_nuclideTable->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch);
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);
layout->addWidget(m_nuclideTable); layout->addWidget(m_nuclideTable);
connect(m_nuclideTable, &QTableWidget::itemSelectionChanged,
this, &NuclideAnalysisView::onNuclideTableSelectionChanged);
} }
void NuclideAnalysisView::queryNuclidesForPeak(const PeakFitResultNuclide& peak) void NuclideAnalysisView::queryNuclidesForPeak(const PeakFitResultNuclide& peak)
{ {
for (QwtPlotMarker* marker : m_selectedNuclideMarkers) {
if (marker) {
marker->detach();
delete marker;
}
}
m_selectedNuclideMarkers.clear();
if (!peak.success) return; if (!peak.success) return;
if (!openNuclideDatabase()) { if (!openNuclideDatabase()) {
@ -753,16 +781,47 @@ void NuclideAnalysisView::queryNuclidesForPeak(const PeakFitResultNuclide& peak)
return qAbs(a.sortValue - center) < qAbs(b.sortValue - center); return qAbs(a.sortValue - center) < qAbs(b.sortValue - center);
}); });
m_nuclideTable->setRowCount(matches.size()); // //单峰显示
for (int i = 0; i < matches.size(); ++i) { // m_nuclideTable->setRowCount(matches.size());
const auto& m = matches[i]; // for (int i = 0; i < matches.size(); ++i) {
m_nuclideTable->setItem(i, 0, new QTableWidgetItem(m.nuclideName)); // const auto& m = matches[i];
m_nuclideTable->setItem(i, 1, new QTableWidgetItem(m.rayType)); // m_nuclideTable->setItem(i, 0, new QTableWidgetItem(m.nuclideName));
m_nuclideTable->setItem(i, 2, new QTableWidgetItem(m.energyDisplay)); // m_nuclideTable->setItem(i, 1, new QTableWidgetItem(m.rayType));
createRowOperationWidgets(i); // m_nuclideTable->setItem(i, 2, new QTableWidgetItem(m.energyDisplay));
// createRowOperationWidgets(i);
// }
// if (matches.isEmpty()) {
// m_nuclideTable->setRowCount(1);
// m_nuclideTable->setItem(0, 0, new QTableWidgetItem(QStringLiteral(u"未找到匹配核素")));
// }
//多峰显示
if (m_nuclideTable->rowCount() > 0) {
QTableWidgetItem* firstItem = m_nuclideTable->item(0, 0);
if (firstItem) {
QString txt = firstItem->text();
if (txt == QStringLiteral(u"未找到匹配核素") ||
txt == QStringLiteral(u"数据库未打开")) {
m_nuclideTable->removeRow(0);
}
}
} }
if (matches.isEmpty()) { // 新匹配结果追加到表格末尾
int startRow = m_nuclideTable->rowCount();
for (int i = 0; i < matches.size(); ++i) {
int row = startRow + i;
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));
createRowOperationWidgets(row);
}
// 表格为空且没匹配到时,才显示提示
if (m_nuclideTable->rowCount() == 0 && matches.isEmpty()) {
m_nuclideTable->setRowCount(1); m_nuclideTable->setRowCount(1);
m_nuclideTable->setItem(0, 0, new QTableWidgetItem(QStringLiteral(u"未找到匹配核素"))); m_nuclideTable->setItem(0, 0, new QTableWidgetItem(QStringLiteral(u"未找到匹配核素")));
} }
@ -833,10 +892,124 @@ void NuclideAnalysisView::onDeleteRow()
void NuclideAnalysisView::onSaveSelectedNuclides() void NuclideAnalysisView::onSaveSelectedNuclides()
{ {
QJsonArray nuclideArray;
for (int i = 0; i < m_nuclideTable->rowCount(); ++i) {
QWidget* widget = m_nuclideTable->cellWidget(i, 3);
if (widget) {
QCheckBox* checkBox = widget->findChild<QCheckBox*>();
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);
if (nuclideItem) {
QJsonObject obj;
obj["nuclide"] = nuclideItem->text();
if (rayTypeItem) {
obj["ray_type"] = rayTypeItem->text();
}
if (energyItem) {
obj["energy_keV"] = energyItem->text();
}
nuclideArray.append(obj);
}
}
}
}
if (nuclideArray.isEmpty()) {
QMessageBox::information(m_nuclideDialog, QStringLiteral(u"提示"),
QStringLiteral(u"请先勾选要保存的核素"));
return;
}
QString savePath = _workspace + "/selected_nuclides.json";
QFile file(savePath);
if (file.open(QIODevice::WriteOnly | QIODevice::Text)) {
QJsonDocument doc(nuclideArray);
file.write(doc.toJson(QJsonDocument::Indented));
file.close();
} else {
QMessageBox::warning(m_nuclideDialog, QStringLiteral(u"保存失败"),
QStringLiteral(u"无法写入文件:%1").arg(savePath));
}
} }
void NuclideAnalysisView::onAddNuclide() void NuclideAnalysisView::onAddNuclide()
{ {
AddNuclideDialog dlg(m_nuclideDialog);
if (dlg.exec() == QDialog::Accepted) {
QList<QStringList>& selectRays = dlg.getSelectRay();
for (const QStringList& ray : selectRays) {
if (ray.size() >= 3) {
QString nuclideName = ray.at(1);
QString energy = ray.at(2);
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));
createRowOperationWidgets(row);
}
}
}
}
void NuclideAnalysisView::onNuclideTableSelectionChanged()
{
// 清除旧竖线
for (QwtPlotMarker* marker : m_selectedNuclideMarkers) {
if (marker) {
marker->detach();
delete marker;
}
}
m_selectedNuclideMarkers.clear();
// 获取选中行
QList<QTableWidgetSelectionRange> ranges = m_nuclideTable->selectedRanges();
if (ranges.isEmpty()) {
_plot->replot();
return;
}
// 遍历选中行,解析能量画竖线
for (const QTableWidgetSelectionRange& range : ranges) {
for (int row = range.topRow(); row <= range.bottomRow(); ++row) {
QTableWidgetItem* item = m_nuclideTable->item(row, 2);
if (!item) continue;
QString str = item->text().trimmed();
if (str.contains('-')) {
// 范围能量,画两条线
QStringList parts = str.split('-');
if (parts.size() == 2) {
bool ok1, ok2;
double low = parts[0].trimmed().toDouble(&ok1);
double high = parts[1].trimmed().toDouble(&ok2);
if (ok1 && ok2) {
addNuclideVLine(low);
addNuclideVLine(high);
}
}
} else {
// 单能量,画一条线
bool ok;
double e = str.toDouble(&ok);
if (ok) addNuclideVLine(e);
}
}
}
_plot->replot();
}
void NuclideAnalysisView::addNuclideVLine(double energy)
{
QwtPlotMarker* marker = new QwtPlotMarker();
marker->setLineStyle(QwtPlotMarker::VLine);
marker->setLinePen(QPen(Qt::green, 2, Qt::SolidLine));
marker->setValue(energy, 0);
marker->attach(_plot);
m_selectedNuclideMarkers.append(marker);
} }

View File

@ -15,6 +15,7 @@
#include <QPushButton> #include <QPushButton>
#include <QCheckBox> #include <QCheckBox>
#include <QHBoxLayout> #include <QHBoxLayout>
#include <QList>
#include "sqlitemanager.h" #include "sqlitemanager.h"
@ -81,6 +82,8 @@ private:
void createRowOperationWidgets(int row); void createRowOperationWidgets(int row);
void addNuclideVLine(double energy);
private slots: private slots:
void onActionPlotConfigure(); void onActionPlotConfigure();
@ -93,6 +96,8 @@ private slots:
void onDeleteRow(); void onDeleteRow();
void onSaveSelectedNuclides(); void onSaveSelectedNuclides();
void onAddNuclide(); void onAddNuclide();
void onNuclideTableSelectionChanged();
private: private:
CustomQwtPlot* _plot = nullptr; CustomQwtPlot* _plot = nullptr;
@ -121,6 +126,8 @@ private:
QTableWidget* m_nuclideTable = nullptr; QTableWidget* m_nuclideTable = nullptr;
QPushButton* m_saveBtn = nullptr; QPushButton* m_saveBtn = nullptr;
QPushButton* m_addBtn = nullptr; // 新增核素按钮 QPushButton* m_addBtn = nullptr; // 新增核素按钮
QList<QwtPlotMarker*> m_selectedNuclideMarkers;
}; };
#endif // NUCLIDEANALYSISVIEW_H #endif // NUCLIDEANALYSISVIEW_H

View File

@ -92,6 +92,7 @@ SOURCES += \
MeasureDeviceParamsConfigView/DeviceParamsSaveToSysDlg.cpp \ MeasureDeviceParamsConfigView/DeviceParamsSaveToSysDlg.cpp \
MeasureDeviceParamsConfigView/DeviceParamsTableForm.cpp \ MeasureDeviceParamsConfigView/DeviceParamsTableForm.cpp \
MeasureDeviceParamsConfigView/MeasureDeviceParamsConfigView.cpp \ MeasureDeviceParamsConfigView/MeasureDeviceParamsConfigView.cpp \
NuclideAnalysisView/AddNuclideDialog.cpp \
NuclideAnalysisView/NuclideAnalysisView.cpp \ NuclideAnalysisView/NuclideAnalysisView.cpp \
NuclideLib/NuclideEditDialog.cpp \ NuclideLib/NuclideEditDialog.cpp \
NuclideLib/NuclideRayDialog.cpp \ NuclideLib/NuclideRayDialog.cpp \
@ -148,6 +149,7 @@ HEADERS += \
MeasureDeviceParamsConfigView/DeviceParamsSaveToSysDlg.h \ MeasureDeviceParamsConfigView/DeviceParamsSaveToSysDlg.h \
MeasureDeviceParamsConfigView/DeviceParamsTableForm.h \ MeasureDeviceParamsConfigView/DeviceParamsTableForm.h \
MeasureDeviceParamsConfigView/MeasureDeviceParamsConfigView.h \ MeasureDeviceParamsConfigView/MeasureDeviceParamsConfigView.h \
NuclideAnalysisView/AddNuclideDialog.h \
NuclideAnalysisView/NuclideAnalysisView.h \ NuclideAnalysisView/NuclideAnalysisView.h \
NuclideLib/NuclideEditDialog.h \ NuclideLib/NuclideEditDialog.h \
NuclideLib/NuclideRayDialog.h \ NuclideLib/NuclideRayDialog.h \
@ -187,6 +189,7 @@ FORMS += \
MeasureDeviceParamsConfigView/DeviceParamsManagerDlg.ui \ MeasureDeviceParamsConfigView/DeviceParamsManagerDlg.ui \
MeasureDeviceParamsConfigView/DeviceParamsSaveToSysDlg.ui \ MeasureDeviceParamsConfigView/DeviceParamsSaveToSysDlg.ui \
MeasureDeviceParamsConfigView/DeviceParamsTableForm.ui \ MeasureDeviceParamsConfigView/DeviceParamsTableForm.ui \
NuclideAnalysisView/AddNuclideDialog.ui \
ParticleCountPlotView/BatchEnergyScaleDialog.ui \ ParticleCountPlotView/BatchEnergyScaleDialog.ui \
NewMeasureAnalysisDlg.ui \ NewMeasureAnalysisDlg.ui \
RegionOfInterest/RegionOfInterest.ui \ RegionOfInterest/RegionOfInterest.ui \