diff --git a/bin/nuclideLib.db b/bin/nuclideLib.db index da005d1..593b2a2 100644 Binary files a/bin/nuclideLib.db and b/bin/nuclideLib.db differ diff --git a/src/2DSpectralCompliance/TwoDSpectralCompliance.cpp b/src/2DSpectralCompliance/TwoDSpectralCompliance.cpp index cc11a74..2fc45a2 100644 --- a/src/2DSpectralCompliance/TwoDSpectralCompliance.cpp +++ b/src/2DSpectralCompliance/TwoDSpectralCompliance.cpp @@ -23,7 +23,10 @@ #include #include #include +#include #include +#include "csv.h" +#include class HeatMapColorMap : public QwtLinearColorMap { public: @@ -65,12 +68,18 @@ void TwoDSpectralCompliance::SetAnalyzeDataFilename(const QMapStart(); - auto functionToRun = [this, csvFile]() { - readCsv(csvFile); + auto functionToRun = [this, _data_filenames]() { + readCsv(_data_filenames); generateSurfaceData(); QMetaObject::invokeMethod(this, [this]() { updateSpectrogram(); @@ -115,37 +124,35 @@ void TwoDSpectralCompliance::setupPlot() _spectrogram->attach(_plot); } -void TwoDSpectralCompliance::readCsv(const QString& filename) +void TwoDSpectralCompliance::readCsv(const QStringList& filename) { - m_rawData.clear(); - QFile file(filename); - if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { - qWarning() << QStringLiteral(u"无法打开文件:") << filename; + if (filename.isEmpty()) { + QMetaObject::invokeMethod(this, [this]() { + _busy_indicator->Stop(); + }, Qt::QueuedConnection); return; } - - QTextStream stream(&file); - QString header = stream.readLine(); - Q_UNUSED(header); - - while (!stream.atEnd()) { - QString line = stream.readLine(); - if (line.isEmpty()) - continue; - - QStringList fields = line.split(','); - if (fields.size() < 5) - continue; - - EventData data; - data.eventId = fields[0].toInt(); - data.board = fields[1].toInt(); - data.channel = fields[2].toInt(); - data.energy = fields[3].toDouble(); - data.timeCounter = fields[4].toULongLong(); - m_rawData.append(data); + for (const QString& filename : filename) { + io::CSVReader<5> in(QStrToSysPath(filename)); + in.read_header(io::ignore_extra_column, + QString(QStringLiteral(u"事件ID")).toStdString(), + QString(QStringLiteral(u"板卡号")).toStdString(), + QString(QStringLiteral(u"通道号")).toStdString(), + QString(QStringLiteral(u"能量(KeV)")).toStdString(), + QString(QStringLiteral(u"时间计数")).toStdString()); + int eventId,board, channel; + double energy; + unsigned long long time_count; + while (in.read_row(eventId,board, channel, energy, time_count)) { + EventData sd; + sd.eventId = eventId; + sd.board = board; + sd.channel = channel; + sd.energy = energy; + sd.timeCounter = time_count; + m_rawData.push_back(sd); + } } - file.close(); } void TwoDSpectralCompliance::generateSurfaceData() diff --git a/src/2DSpectralCompliance/TwoDSpectralCompliance.h b/src/2DSpectralCompliance/TwoDSpectralCompliance.h index e1cc9a3..d3bd3ff 100644 --- a/src/2DSpectralCompliance/TwoDSpectralCompliance.h +++ b/src/2DSpectralCompliance/TwoDSpectralCompliance.h @@ -39,7 +39,7 @@ protected: private: void setupPlot(); - void readCsv(const QString& filename); + void readCsv(const QStringList& filename); void generateSurfaceData(); void updateSpectrogram(); diff --git a/src/EnergyCountPeakFitView/EnergyCountPeakFitView.cpp b/src/EnergyCountPeakFitView/EnergyCountPeakFitView.cpp index 73a9133..ec20630 100644 --- a/src/EnergyCountPeakFitView/EnergyCountPeakFitView.cpp +++ b/src/EnergyCountPeakFitView/EnergyCountPeakFitView.cpp @@ -25,7 +25,6 @@ #include #include "PlotRectItem.h" #include -#include #include #include #include @@ -223,7 +222,7 @@ void EnergyCountPeakFitView::setupPlot() dummyFit->attach(_plot); QwtPlotCurve *dummyBg = new QwtPlotCurve(QStringLiteral(u"本底数据")); - dummyBg->setPen(QPen(Qt::yellow, 2)); + dummyBg->setPen(QPen(QColor("#C9A84C"), 2)); dummyBg->setSamples(QVector(), QVector()); dummyBg->setVisible(false); dummyBg->attach(_plot); @@ -551,7 +550,7 @@ void EnergyCountPeakFitView::fadeSelectionRectBorders() { for (PlotRectItem* item : _selectionRectItems) { if (item) { - QPen fadedPen(Qt::red, 1, Qt::DashLine); + QPen fadedPen(Qt::red, 2, Qt::DashLine); item->setPen(fadedPen); } } @@ -593,12 +592,12 @@ QList EnergyCountPeakFitView::performPeakFitting(const QVector EnergyCountPeakFitView::createFitCurve(const PeakFitResult curveList.append(curve); QwtPlotCurve* curveTw = new QwtPlotCurve(QStringLiteral(u"本底数据")); - curveTw->setPen(QPen(Qt::yellow, 2)); + curveTw->setPen(QPen(QColor("#C9A84C"), 2)); curveTw->setSamples(xs, ysTw); curveTw->setItemAttribute(QwtPlotItem::Legend, false); curveTw->attach(_plot); @@ -679,6 +678,64 @@ QList EnergyCountPeakFitView::createFitCurve(const PeakFitResult return curveList; } +void EnergyCountPeakFitView::updateHistoryDialogWithSelection(const QList &selectedRefs) +{ + if (!_historyDlg) return; + + QTableView* tableView = _historyDlg->findChild("historyTableView"); + QStandardItemModel* model = qobject_cast(tableView ? tableView->model() : nullptr); + if (!model) return; + + // 将选中的引用转换为集合,方便快速查找 + QSet> selectedSet; + for (const auto& ref : selectedRefs) { + selectedSet.insert(qMakePair(ref.historyIndex, ref.curveIndex)); + } + + // 重新构建表格 + model->clear(); + QStringList headers; + headers << "序号" << "振幅(A)" << "高斯宽度(delt)" << "Sigmoid幅度(H)" << "Sigmoid宽度(W)" << "基线(C)"; + model->setHorizontalHeaderLabels(headers); + + QVector> newRowMap; + model->blockSignals(true); + int rowNumber = 1; + + for (int historyIdx = 0; historyIdx < _fitHistoryList.size(); ++historyIdx) { + const auto& historyItem = _fitHistoryList[historyIdx]; + for (int curveIdx = 0; curveIdx < historyItem.curveList.size(); ++curveIdx) { + const auto& curve = historyItem.curveList[curveIdx]; + QList rowItems; + + QStandardItem* checkItem = new QStandardItem(QString::number(rowNumber++)); + checkItem->setCheckable(true); + checkItem->setEditable(false); + checkItem->setCheckState(selectedSet.contains(qMakePair(historyIdx, curveIdx)) + ? Qt::Checked : Qt::Unchecked); + rowItems.append(checkItem); + + rowItems.append(new QStandardItem(QString::number(curve.amplitude, 'f', 4))); + rowItems.append(new QStandardItem(QString::number(curve.sigma, 'f', 4))); + rowItems.append(new QStandardItem(QString::number(curve.sigmoidH, 'f', 4))); + rowItems.append(new QStandardItem(QString::number(curve.sigmoidW, 'f', 4))); + rowItems.append(new QStandardItem(QString::number(curve.baseline, 'f', 4))); + + model->appendRow(rowItems); + newRowMap.append(qMakePair(historyIdx, curveIdx)); + } + } + + model->blockSignals(false); + _historyDlg->setProperty("rowToDataIndices", QVariant::fromValue(newRowMap)); + tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); + tableView->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Fixed); + tableView->horizontalHeader()->resizeSection(0, 70); + tableView->horizontalHeader()->setStretchLastSection(true); + tableView->viewport()->update(); + LOG_DEBUG(QStringLiteral(u"历史对话框已更新")); +} + void EnergyCountPeakFitView::clearFitCurves() { @@ -776,17 +833,18 @@ void EnergyCountPeakFitView::onActionShowFitHistory() break; } } - if (!hasCurveData) { - QMessageBox* msgBox = new QMessageBox(this); - msgBox->setWindowTitle(QStringLiteral(u"峰拟合结果")); - msgBox->setText(QStringLiteral(u"暂无历史拟合数据,请先进行拟合并保存。")); - msgBox->setStandardButtons(QMessageBox::Ok); - msgBox->setModal(false); - msgBox->setAttribute(Qt::WA_DeleteOnClose); - msgBox->setWindowFlags(Qt::Dialog | Qt::WindowCloseButtonHint); - msgBox->show(); - return; - } + //空表时直接打开 + // if (!hasCurveData) { + // QMessageBox* msgBox = new QMessageBox(this); + // msgBox->setWindowTitle(QStringLiteral(u"峰拟合结果")); + // msgBox->setText(QStringLiteral(u"暂无历史拟合数据,请先进行拟合并保存。")); + // msgBox->setStandardButtons(QMessageBox::Ok); + // msgBox->setModal(false); + // msgBox->setAttribute(Qt::WA_DeleteOnClose); + // msgBox->setWindowFlags(Qt::Dialog | Qt::WindowCloseButtonHint); + // msgBox->show(); + // return; + // } if (_historyDlg) { _historyDlg->raise(); @@ -852,9 +910,15 @@ void EnergyCountPeakFitView::onActionShowFitHistory() tableView->setSelectionBehavior(QAbstractItemView::SelectRows); tableView->setSelectionMode(QAbstractItemView::SingleSelection); tableView->setEditTriggers(QAbstractItemView::NoEditTriggers); - tableView->horizontalHeader()->setStretchLastSection(true); tableView->verticalHeader()->setVisible(false); + + // 关键:先设置所有列为拉伸模式 tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); + // 再单独将序号列(第0列)设置为固定宽度 + tableView->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Fixed); + tableView->horizontalHeader()->resizeSection(0, 70); + // 最后设置最后一列拉伸 + tableView->horizontalHeader()->setStretchLastSection(true); layout->addWidget(tableView); QPushButton* btnDelete = new QPushButton(QStringLiteral(u"删除选中记录"), _historyDlg); @@ -1015,8 +1079,10 @@ void EnergyCountPeakFitView::onActionShowFitHistory() } saveHistoryToFile(); - - emit newFitResultAdded(); + if (_historyDlg) { + updateHistoryDialogWithSelection(remainingRefs); + } + // emit newFitResultAdded(); } }); confirmBox->show(); @@ -1028,6 +1094,71 @@ void EnergyCountPeakFitView::onActionShowFitHistory() void EnergyCountPeakFitView::onActionDeleteHoveredRect() { + // if (!_hoveredRectItem) { + // QMessageBox::information(this, QStringLiteral(u"提示"), + // QStringLiteral(u"请先将鼠标移动到要删除的框选区域上(区域边框会变为实线),然后再点击此菜单。")); + // return; + // } + // QString rectType = _hoveredRectItem->selectionType(); + // int historyIndex = _hoveredRectItem->selectionIndex(); + + // int curveStartIdx = historyIndex * 2; + // if (curveStartIdx + 1 < _fitCurves.size()) { + // _fitCurves[curveStartIdx + 1]->detach(); + // delete _fitCurves[curveStartIdx + 1]; + // _fitCurves.removeAt(curveStartIdx + 1); + // _fitCurves[curveStartIdx]->detach(); + // delete _fitCurves[curveStartIdx]; + // _fitCurves.removeAt(curveStartIdx); + // } + + // _hoveredRectItem->detach(); + // delete _hoveredRectItem; + // for (auto it = _selectionRectItems.begin(); it != _selectionRectItems.end();) { + // if (*it && (*it)->selectionIndex() == historyIndex) { + // it = _selectionRectItems.erase(it); + // } else { + // ++it; + // } + // } + // _hoveredRectItem = nullptr; + + // if (historyIndex >= 0 && historyIndex < _fitHistoryList.size()) { + // _fitHistoryList.removeAt(historyIndex); + // saveHistoryToFile(); + // } + + // for (auto& ref : _displayedHistoryCurves) { + // if (ref.historyIndex > historyIndex) { + // ref.historyIndex--; + // ref.rectIndex = ref.historyIndex; + // ref.curveStartIndex = ref.rectIndex * 2; + // } + // } + // for (auto it = _displayedHistoryCurves.begin(); it != _displayedHistoryCurves.end();) { + // if (it->historyIndex == historyIndex) { + // it = _displayedHistoryCurves.erase(it); + // } else { + // ++it; + // } + // } + + // for (PlotRectItem* item : _selectionRectItems) { + // if (item && item->selectionIndex() > historyIndex) { + // item->setSelectionIndex(item->selectionIndex() - 1); + // } + // } + + // for (auto& record : _currentFitRecords) { + // if (record.historyIndex > historyIndex) { + // record.historyIndex--; + // } + // } + + // _plot->replot(); + + + // emit newFitResultAdded(); if (!_hoveredRectItem) { QMessageBox::information(this, QStringLiteral(u"提示"), QStringLiteral(u"请先将鼠标移动到要删除的框选区域上(区域边框会变为实线),然后再点击此菜单。")); @@ -1035,7 +1166,6 @@ void EnergyCountPeakFitView::onActionDeleteHoveredRect() } QString rectType = _hoveredRectItem->selectionType(); int historyIndex = _hoveredRectItem->selectionIndex(); - int curveStartIdx = historyIndex * 2; if (curveStartIdx + 1 < _fitCurves.size()) { _fitCurves[curveStartIdx + 1]->detach(); @@ -1045,7 +1175,6 @@ void EnergyCountPeakFitView::onActionDeleteHoveredRect() delete _fitCurves[curveStartIdx]; _fitCurves.removeAt(curveStartIdx); } - _hoveredRectItem->detach(); delete _hoveredRectItem; for (auto it = _selectionRectItems.begin(); it != _selectionRectItems.end();) { @@ -1056,41 +1185,52 @@ void EnergyCountPeakFitView::onActionDeleteHoveredRect() } } _hoveredRectItem = nullptr; - if (historyIndex >= 0 && historyIndex < _fitHistoryList.size()) { _fitHistoryList.removeAt(historyIndex); saveHistoryToFile(); } + QList remainingRefs; for (auto& ref : _displayedHistoryCurves) { + if (ref.historyIndex == historyIndex) { + continue; // 跳过要删除的记录 + } if (ref.historyIndex > historyIndex) { ref.historyIndex--; ref.rectIndex = ref.historyIndex; ref.curveStartIndex = ref.rectIndex * 2; } + remainingRefs.append(ref); } - for (auto it = _displayedHistoryCurves.begin(); it != _displayedHistoryCurves.end();) { - if (it->historyIndex == historyIndex) { - it = _displayedHistoryCurves.erase(it); - } else { - ++it; - } - } + + _displayedHistoryCurves = remainingRefs; for (PlotRectItem* item : _selectionRectItems) { if (item && item->selectionIndex() > historyIndex) { item->setSelectionIndex(item->selectionIndex() - 1); } } - for (auto& record : _currentFitRecords) { if (record.historyIndex > historyIndex) { record.historyIndex--; } } - _plot->replot(); - emit newFitResultAdded(); + clearFitCurves(); + clearAllSelectionRects(); + if (!remainingRefs.isEmpty()) { + QList remainingCurves; + for (const auto& ref : remainingRefs) { + remainingCurves.append(_fitHistoryList[ref.historyIndex].curveList[ref.curveIndex]); + } + displaySelectedCurves(remainingCurves, remainingRefs); + } else { + _plot->replot(); + } + + if (_historyDlg) { + updateHistoryDialogWithSelection(remainingRefs); + } } void EnergyCountPeakFitView::onActionRefitCurrentRect() @@ -1300,7 +1440,7 @@ void EnergyCountPeakFitView::displaySelectedCurves(const QList &cu for (int j = 0; j < yTw.size(); ++j) ysTw.append(yTw(j)); QwtPlotCurve* bgCurve = new QwtPlotCurve(QStringLiteral(u"历史本底数据")); - bgCurve->setPen(QPen(Qt::yellow, 2, Qt::DashLine)); + bgCurve->setPen(QPen(QColor("#C9A84C"), 2, Qt::DashLine)); bgCurve->setSamples(xs, ysTw); bgCurve->setItemAttribute(QwtPlotItem::Legend, false); bgCurve->attach(_plot); @@ -1423,7 +1563,10 @@ void EnergyCountPeakFitView::onNewFitResultAdded() } } displaySelectedCurves(selectedCurves, selectedRefs); - + tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); + tableView->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Fixed); + tableView->horizontalHeader()->resizeSection(0, 70); + tableView->horizontalHeader()->setStretchLastSection(true); tableView->viewport()->update(); LOG_DEBUG(QStringLiteral(u"历史对话框已同步刷新")); } diff --git a/src/EnergyCountPeakFitView/EnergyCountPeakFitView.h b/src/EnergyCountPeakFitView/EnergyCountPeakFitView.h index d81b3b3..5471f51 100644 --- a/src/EnergyCountPeakFitView/EnergyCountPeakFitView.h +++ b/src/EnergyCountPeakFitView/EnergyCountPeakFitView.h @@ -129,6 +129,8 @@ private: QList performPeakFitting(const QVector& x, const QVector& y /*, const arma::vec* userP0 = nullptr*/); // 根据拟合参数生成曲线 QList createFitCurve(const PeakFitResult& result, arma::vec xVec); + // 更新历史对话框并保持指定的选中状态 + void updateHistoryDialogWithSelection(const QList& selectedRefs); signals: void newFitResultAdded(); diff --git a/src/EnergyCountPeakFitView/PlotRectItem.cpp b/src/EnergyCountPeakFitView/PlotRectItem.cpp index 41f645c..465cd36 100644 --- a/src/EnergyCountPeakFitView/PlotRectItem.cpp +++ b/src/EnergyCountPeakFitView/PlotRectItem.cpp @@ -13,6 +13,10 @@ PlotRectItem::PlotRectItem(const QString &title) m_hoverPen = QPen(Qt::red, 2, Qt::SolidLine); m_brush = QBrush(QColor(255, 0, 0, 30)); + + m_normalTextPen = QPen(Qt::gray); // 普通状态黑色文本 + m_hoverTextPen = QPen(Qt::black); // 悬停状态高亮黑色文本 + m_hoverTextPen.setWidth(1); // 稍微加粗 } void PlotRectItem::setRect(const QRectF &rect) { @@ -98,6 +102,10 @@ void PlotRectItem::draw(QPainter *painter, // 绘制半透明背景框(增强可读性) QFont font = painter->font(); font.setPointSize(9); // 稍微小一点 + // 悬停时加粗字体 + // if (m_isHovered) { + // font.setBold(true); + // } painter->setFont(font); QFontMetrics fm(font); @@ -105,8 +113,8 @@ void PlotRectItem::draw(QPainter *painter, textRect.moveTopLeft(textPos); textRect.adjust(-5, -3, 5, 3); // 增加边距 - painter->fillRect(textRect, QColor(255, 255, 255, 220)); // 白底微透 - painter->setPen(Qt::black); + painter->fillRect(textRect, QColor(255, 255, 255, 0)); // 白底微透 + painter->setPen(m_isHovered ? m_hoverTextPen : m_normalTextPen); painter->drawText(textRect, Qt::AlignLeft, text); painter->restore(); diff --git a/src/EnergyCountPeakFitView/PlotRectItem.h b/src/EnergyCountPeakFitView/PlotRectItem.h index 2fabf4d..175c807 100644 --- a/src/EnergyCountPeakFitView/PlotRectItem.h +++ b/src/EnergyCountPeakFitView/PlotRectItem.h @@ -38,6 +38,8 @@ private: QPen m_normalPen; //普通状态画笔(虚线) QPen m_hoverPen; //悬停状态画笔(实线) QBrush m_brush; + QPen m_normalTextPen; // 普通状态文本画笔 + QPen m_hoverTextPen; // 悬停状态高亮文本画笔 bool m_isHovered; //悬停状态标志 diff --git a/src/NuclideLib/NuclideEditDialog.cpp b/src/NuclideLib/NuclideEditDialog.cpp index d40996d..cedfc93 100644 --- a/src/NuclideLib/NuclideEditDialog.cpp +++ b/src/NuclideLib/NuclideEditDialog.cpp @@ -71,12 +71,6 @@ bool NuclideEditDialog::validateInput() } bool ok; - // 半衰期校验(保留原逻辑,TEXT类型可存储带单位的字符串) - m_leHalfLife->text().toDouble(&ok); - if (!ok) { - QMessageBox::warning(this, "输入错误", "半衰期必须为数字(可带单位,如12.5d)!"); - return false; - } m_leHalfLifeUnc->text().toDouble(&ok); if (!ok) { QMessageBox::warning(this, "输入错误", "半衰期不确定度必须为有效数字!"); diff --git a/src/NuclideLib/NuclideLib.cpp b/src/NuclideLib/NuclideLib.cpp index 5359902..7bfc4e0 100644 --- a/src/NuclideLib/NuclideLib.cpp +++ b/src/NuclideLib/NuclideLib.cpp @@ -16,7 +16,12 @@ void ButtonDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option { if (index.column() == 7) { QStyleOptionButton button; - button.rect = option.rect; + const int btnWidth = 180; // 按钮宽度(可根据需要调整) + const int btnHeight = option.rect.height() - 4; // 按钮高度(上下各留2px边距) + const int x = option.rect.x() + (option.rect.width() - btnWidth) / 2; // 水平居中 + const int y = option.rect.y() + 2; // 垂直居中(上下边距) + button.rect = QRect(x, y, btnWidth, btnHeight); + // button.rect = option.rect; button.text = QStringLiteral(u"核素发射射线信息"); button.state = QStyle::State_Enabled; if (option.state & QStyle::State_MouseOver) @@ -53,7 +58,7 @@ NuclideLibManage::NuclideLibManage(QWidget *parent) : ui->tableView->setColumnHidden(0, true); ui->tableView->setColumnWidth(1, 90); // 序号 - ui->tableView->setColumnWidth(7, 280); // 操作列 + ui->tableView->setColumnWidth(7, 180); // 操作列 ui->tableView->horizontalHeader()->setSectionResizeMode(2, QHeaderView::Stretch); ui->tableView->horizontalHeader()->setSectionResizeMode(3, QHeaderView::Stretch); ui->tableView->horizontalHeader()->setSectionResizeMode(4, QHeaderView::Stretch); @@ -159,8 +164,8 @@ void NuclideLibManage::on_pushButton_add_clicked() qint64 newId = SqliteManager::instance().insertRow("nuclideLib", fieldValues); if (newId > 0) { - QMessageBox::information(this, QStringLiteral(u"成功"), QStringLiteral(u"核素添加成功!")); loadNuclideData(); + QMessageBox::information(this, QStringLiteral(u"成功"), QStringLiteral(u"核素添加成功!")); } else { QMessageBox::warning(this, QStringLiteral(u"失败"), QStringLiteral(u"添加失败:") + SqliteManager::instance().lastError()); } @@ -219,19 +224,50 @@ void NuclideLibManage::on_pushButton_del_clicked() } int row = selected.first().row(); - QString id = m_model->index(row, 0).data().toString(); + QString nuclideId = m_model->index(row, 0).data().toString(); - QMessageBox box(QMessageBox::Question, QStringLiteral(u"提示"), QStringLiteral(u"确定删除该核素吗?"), + QMessageBox box(QMessageBox::Question, QStringLiteral(u"提示"), + QStringLiteral(u"确定删除该核素及其所有关联的射线信息吗?"), QMessageBox::Yes | QMessageBox::No, this); box.button(QMessageBox::Yes)->setText(QStringLiteral(u"确认")); box.button(QMessageBox::No)->setText(QStringLiteral(u"取消")); if (box.exec() != QMessageBox::Yes) return; - bool ok = SqliteManager::instance().deleteRow("nuclideLib", "ID = ?", {id}); - if (ok) { - loadNuclideData(); + SqliteManager& dbMgr = SqliteManager::instance(); + // 开始事务 + if (!dbMgr.beginTransaction()) { + QMessageBox::warning(this, QStringLiteral(u"错误"), + QStringLiteral(u"开启事务失败:") + dbMgr.lastError()); + return; + } + + // 步骤1:删除该核素关联的所有射线信息 + int rayDelCount = dbMgr.deleteRow("nuclideRayInfo", "NUCLIDE_ID = ?", {nuclideId.toInt()}); + if (rayDelCount == -1) { // 删除射线失败 + dbMgr.rollbackTransaction(); // 回滚事务 + QMessageBox::warning(this, QStringLiteral(u"错误"), + QStringLiteral(u"删除关联射线信息失败:") + dbMgr.lastError()); + return; + } + + // 步骤2:删除核素本身 + int nuclideDelCount = dbMgr.deleteRow("nuclideLib", "ID = ?", {nuclideId}); + if (nuclideDelCount == -1) { // 删除核素失败 + dbMgr.rollbackTransaction(); // 回滚事务 + QMessageBox::warning(this, QStringLiteral(u"错误"), + QStringLiteral(u"删除核素失败:") + dbMgr.lastError()); + return; + } + + // 提交事务(所有操作成功) + if (dbMgr.commitTransaction()) { + QMessageBox::information(this, QStringLiteral(u"成功"), + QStringLiteral(u"核素及关联的%1条射线信息已删除!").arg(rayDelCount)); + loadNuclideData(); // 刷新核素列表 } else { - QMessageBox::warning(this, QStringLiteral(u"错误"), QStringLiteral(u"删除失败:") + SqliteManager::instance().lastError()); + dbMgr.rollbackTransaction(); + QMessageBox::warning(this, QStringLiteral(u"错误"), + QStringLiteral(u"提交事务失败:") + dbMgr.lastError()); } } diff --git a/src/NuclideLib/NuclideLib.ui b/src/NuclideLib/NuclideLib.ui index dcae1e1..6f18f77 100644 --- a/src/NuclideLib/NuclideLib.ui +++ b/src/NuclideLib/NuclideLib.ui @@ -11,7 +11,7 @@ - NuclideLibManage + 核素库 diff --git a/src/NuclideLib/NuclideRayListDialog.cpp b/src/NuclideLib/NuclideRayListDialog.cpp index 8424927..7fa8a4d 100644 --- a/src/NuclideLib/NuclideRayListDialog.cpp +++ b/src/NuclideLib/NuclideRayListDialog.cpp @@ -182,8 +182,8 @@ void NuclideRayListDialog::onAddRayClicked() qint64 newId = SqliteManager::instance().insertRow("nuclideRayInfo", fieldValues); if (newId > 0) { - QMessageBox::information(this, QStringLiteral(u"成功"), QStringLiteral(u"射线信息添加成功!")); loadRayData(); // 刷新列表 + QMessageBox::information(this, QStringLiteral(u"成功"), QStringLiteral(u"射线信息添加成功!")); } else { QMessageBox::warning(this, QStringLiteral(u"失败"), QStringLiteral(u"添加失败:") + SqliteManager::instance().lastError()); }