diff --git a/src/CountRateAnalysisView/CountRateAnalysisView.cpp b/src/CountRateAnalysisView/CountRateAnalysisView.cpp index 62e02ef..6297a94 100644 --- a/src/CountRateAnalysisView/CountRateAnalysisView.cpp +++ b/src/CountRateAnalysisView/CountRateAnalysisView.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -77,12 +78,25 @@ void CountRateAnalysisView::showEvent(QShowEvent *e) void CountRateAnalysisView::setData(QVector data) { + // 缓存原始数据,供修改统计参数后重算使用 + m_rawData = data; + int energyStart = ui->label_energyStart->text().toInt(); int energyEnd = ui->label_energyEnd->text().toInt(); - int nInv = 1; + int nInv = m_statIntervalSec; constexpr qint64 NS_PER_SECOND = 1000000000; // 纳秒转秒的基数 if (data.isEmpty()) return; // 添加空列表保护 + + // 清除旧曲线,避免重算时叠加 + const QwtPlotItemList& oldItems = plot->itemList(); + for (QwtPlotItem* item : oldItems) { + if (item->rtti() == QwtPlotItem::Rtti_PlotCurve) { + item->detach(); + delete item; + } + } + QVector x; QVector y; @@ -115,8 +129,18 @@ void CountRateAnalysisView::setData(QVector data) // 创建曲线并设置数据 QwtPlotCurve *curve = new QwtPlotCurve(); curve->setSamples(vecXpt, vec); - // 将曲线添加到 CustomQwtPlot 中(会自动分配颜色) + curve->setSamples(vecXpt, vec); plot->AddCurve(curve); + + // 保持颜色一致:首次保存自动分配的颜色,后续重算恢复该颜色 + if (m_curveColor.isValid()) { + QPen pen = curve->pen(); + pen.setColor(m_curveColor); + curve->setPen(pen); + } else { + m_curveColor = curve->pen().color(); + } + // 将曲线添加到 CustomQwtPlot 中(会自动分配颜色) // 设置坐标轴范围和标题 // plot->setAxisScale(QwtPlot::xBottom, 0, x.last()); // plot->setAxisScale(QwtPlot::yLeft,minValue , maxValue); @@ -275,7 +299,7 @@ void CountRateAnalysisView::onActionPlotConfigure() layout->addLayout(btnLayout); colorBtnList.append(colorBtn); - connect(colorBtn, &QPushButton::clicked, [&dlg, curve, &curveColorMap, colorBtn]() { + connect(colorBtn, &QPushButton::clicked, [&dlg, curve, &curveColorMap, colorBtn ]() { QColor current = curveColorMap.value(curve); QColor selected = QColorDialog::getColor(current, &dlg, QStringLiteral(u"选择曲线颜色")); if (selected.isValid()) { @@ -330,7 +354,80 @@ void CountRateAnalysisView::onActionPlotConfigure() pen.setColor(curveColorMap.value(curve)); curve->setPen(pen); } + + // 同步更新颜色缓存,确保后续重算时保持用户在图表配置中设置的颜色 + if (!curveList.isEmpty()) { + m_curveColor = curveList.first()->pen().color(); + } // 刷新绘图 plot->replot(); } } + +void CountRateAnalysisView::on_pushButton_clicked() +{ + QDialog dlg(this); + dlg.setWindowTitle(QStringLiteral(u"计数率统计时间设置")); + dlg.setMinimumWidth(320); + + QVBoxLayout* layout = new QVBoxLayout(&dlg); + + // 统计时间间隔 + QHBoxLayout* intervalLayout = new QHBoxLayout(); + QLabel* intervalLabel = new QLabel(QStringLiteral(u"统计时间间隔:"), &dlg); + QSpinBox* intervalSpin = new QSpinBox(&dlg); + intervalSpin->setRange(1, 3600); // 范围:1秒 ~ 1小时 + intervalSpin->setSingleStep(1); + intervalSpin->setValue(m_statIntervalSec); + intervalSpin->setSuffix(QStringLiteral(u" s")); + intervalLayout->addWidget(intervalLabel); + intervalLayout->addWidget(intervalSpin); + intervalLayout->addStretch(); + layout->addLayout(intervalLayout); + + layout->addSpacing(8); + + // 特征峰能量 + QHBoxLayout* energyLayout = new QHBoxLayout(); + QLabel* energyLabel = new QLabel(QStringLiteral(u"特征峰能量:"), &dlg); + QSpinBox* energySpin = new QSpinBox(&dlg); + energySpin->setRange(0, 10000); // 范围:0 ~ 10000 KeV + energySpin->setSingleStep(1); + energySpin->setValue(m_peakEnergy); + energySpin->setSuffix(QStringLiteral(u" KeV")); + energyLayout->addWidget(energyLabel); + energyLayout->addWidget(energySpin); + energyLayout->addStretch(); + layout->addLayout(energyLayout); + + layout->addSpacing(12); + layout->addStretch(); + + // 确定取消按钮 + QDialogButtonBox* buttonBox = new QDialogButtonBox( + QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, &dlg); + layout->addWidget(buttonBox); + + connect(buttonBox, &QDialogButtonBox::accepted, &dlg, &QDialog::accept); + connect(buttonBox, &QDialogButtonBox::rejected, &dlg, &QDialog::reject); + + if (dlg.exec() == QDialog::Accepted) { + int newInterval = intervalSpin->value(); + if (newInterval <= 0) { + QMessageBox::warning(this, QStringLiteral(u"提示"), + QStringLiteral(u"统计时间间隔必须大于0!")); + return; + } + m_statIntervalSec = newInterval; + m_peakEnergy = energySpin->value(); + + // 更新顶部标签显示 + ui->label_energyStart->setText(QString::number(m_statIntervalSec)); + ui->label_energyEnd->setText(QString::number(m_peakEnergy)); + + // 若已有原始数据,立即重算并刷新图表 + if (!m_rawData.isEmpty()) { + setData(m_rawData); + } + } +} diff --git a/src/CountRateAnalysisView/CountRateAnalysisView.h b/src/CountRateAnalysisView/CountRateAnalysisView.h index ef5527f..e437c67 100644 --- a/src/CountRateAnalysisView/CountRateAnalysisView.h +++ b/src/CountRateAnalysisView/CountRateAnalysisView.h @@ -9,7 +9,7 @@ class CustomQwtPlot; class BusyIndicatorWidget; class QMenu; - +class QwtPlotCurve; namespace Ui { class CountRateAnalysisView; } @@ -39,11 +39,17 @@ private: private slots: void onActionPlotConfigure(); + void on_pushButton_clicked(); + private: Ui::CountRateAnalysisView *ui; BusyIndicatorWidget* _busy_indicator = nullptr; CustomQwtPlot *plot; QMenu* _menu = nullptr; + QColor m_curveColor; + int m_statIntervalSec = 1; //计数率统计时间间隔(秒) + int m_peakEnergy = 45; // 特征峰能量(KeV) + QVector m_rawData; // 原始粒子注入时间数据缓存,用于修改设置后重算 }; #endif //COUNTRATEANALYSIS_H diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp index 154ed30..9f30432 100644 --- a/src/MainWindow.cpp +++ b/src/MainWindow.cpp @@ -172,8 +172,6 @@ void MainWindow::onMeasureStopped(bool success, const QString& message) { Q_UNUSED(message); if (success) { - // ui->action_start_measure->setEnabled(true); - // ui->action_stop_measure->setEnabled(false); m_AddressCountTimer->stop(); m_EnergyCountTimer->stop(); LOG_INFO(message); @@ -187,6 +185,63 @@ void MainWindow::onMeasureStopped(bool success, const QString& message) // } // } // } + MeasureAnalysisProjectModel* pro_model = ProjectList::Instance()->GetCurrentProjectModel(); + if (!pro_model) + return; + + const QString& project_name = pro_model->GetProjectName(); + + // 从 ProjectList 获取项目的所有节点(比 nodeMap 更可靠) + QMap > all_nodes = + ProjectList::Instance()->getProjectNodeItems(); + if (!all_nodes.contains(project_name)) + return; + + QMap project_nodes = all_nodes[project_name]; + if (project_nodes.isEmpty()) + return; + + // 更新项目根节点状态:测量中 → 已停止 + QStandardItem* project_item = project_nodes[project_name]; + if (project_item) { + ProjectList::Instance()->SetNodeStatus(project_item, "已停止", false); + } + + // 粒子时间差分析(依赖全通道粒子数据,停止测量时已有) + QStandardItem* time_diff_item = project_nodes[QStringLiteral(u"粒子时间差分析")]; + if (time_diff_item) { + bool status_ok = !pro_model->GetAllChannelParticleDataFilename().isEmpty(); + QString status = status_ok ? QStringLiteral(u"有效") : QStringLiteral(u"无效"); + ProjectList::Instance()->SetNodeStatus(time_diff_item, status, status_ok); + } + + + // 标记测量完成并保存项目模型 + pro_model->SetIsMeasureComplete(true); + pro_model->SaveProjectModel(); + + const QString& all_channel_particle_data_filename = pro_model->GetAllChannelParticleDataFilename(); + if (!all_channel_particle_data_filename.isEmpty()) { + const QString& all_ch_count_dir = pro_model->GetProjectDir(); + const QString& every_ch_count_dir = QDir(pro_model->GetProjectDir()).filePath(QStringLiteral(u"通道道址计数")); + + auto count_task = new DataProcessWorkPool::EveryChannelParticleCountDataTask; + count_task->SetAllChannelParticleDataFilename(all_channel_particle_data_filename); + count_task->SetAllChannelCountResultDir(all_ch_count_dir); + count_task->SetEveryChannelCountResultDir(every_ch_count_dir); + count_task->SetFinishedNotifier(ProjectList::Instance(), "onChannelAddressCountProcessFinished", project_name); + count_task->StartTask(); + } + + if (!all_channel_particle_data_filename.isEmpty()) { + auto coincidence_task = new DataProcessWorkPool::CoincidenceEventAnalysisTask; + coincidence_task->SetFinishedNotifier( + ProjectList::Instance(), + "onCoincidenceProcessFinished", + project_name + ); + coincidence_task->StartTask(); + } } } diff --git a/src/MeasureAnalysisProjectModel.cpp b/src/MeasureAnalysisProjectModel.cpp index 8aa639d..9a16494 100644 --- a/src/MeasureAnalysisProjectModel.cpp +++ b/src/MeasureAnalysisProjectModel.cpp @@ -865,6 +865,12 @@ void MeasureAnalysisProjectModelList::onChannelAddressCountProcessFinished(bool auto adrr_count_spec_item = node_map[adrr_count_spec_item_name]; this->SetNodeStatus(adrr_count_spec_item, status, status_ok); } + + const QString& particle_time_diff_item_name = QStringLiteral(u"粒子时间差分析"); + if (node_map.contains(particle_time_diff_item_name)) { + auto particle_time_diff_item = node_map[particle_time_diff_item_name]; + this->SetNodeStatus(particle_time_diff_item, status, status_ok); + } pro_model->SaveProjectModel(); if ( !pro_model->GetEnergyScaleFilename().isEmpty() ) {