新增计数率统计时间设置

This commit is contained in:
anxinglong 2026-07-29 18:05:03 +08:00
parent 0228b347ce
commit 78304ac19a
4 changed files with 170 additions and 6 deletions

View File

@ -10,6 +10,7 @@
#include <QCheckBox> #include <QCheckBox>
#include <QDialogButtonBox> #include <QDialogButtonBox>
#include <QColorDialog> #include <QColorDialog>
#include <QSpinBox>
#include <QMap> #include <QMap>
#include <QwtPlotCurve> #include <QwtPlotCurve>
#include <QwtPlotMarker> #include <QwtPlotMarker>
@ -77,12 +78,25 @@ void CountRateAnalysisView::showEvent(QShowEvent *e)
void CountRateAnalysisView::setData(QVector<ParticleInjectTime> data) void CountRateAnalysisView::setData(QVector<ParticleInjectTime> data)
{ {
// 缓存原始数据,供修改统计参数后重算使用
m_rawData = data;
int energyStart = ui->label_energyStart->text().toInt(); int energyStart = ui->label_energyStart->text().toInt();
int energyEnd = ui->label_energyEnd->text().toInt(); int energyEnd = ui->label_energyEnd->text().toInt();
int nInv = 1; int nInv = m_statIntervalSec;
constexpr qint64 NS_PER_SECOND = 1000000000; // 纳秒转秒的基数 constexpr qint64 NS_PER_SECOND = 1000000000; // 纳秒转秒的基数
if (data.isEmpty()) return; // 添加空列表保护 if (data.isEmpty()) return; // 添加空列表保护
// 清除旧曲线,避免重算时叠加
const QwtPlotItemList& oldItems = plot->itemList();
for (QwtPlotItem* item : oldItems) {
if (item->rtti() == QwtPlotItem::Rtti_PlotCurve) {
item->detach();
delete item;
}
}
QVector<double> x; QVector<double> x;
QVector<double> y; QVector<double> y;
@ -115,8 +129,18 @@ void CountRateAnalysisView::setData(QVector<ParticleInjectTime> data)
// 创建曲线并设置数据 // 创建曲线并设置数据
QwtPlotCurve *curve = new QwtPlotCurve(); QwtPlotCurve *curve = new QwtPlotCurve();
curve->setSamples(vecXpt, vec); curve->setSamples(vecXpt, vec);
// 将曲线添加到 CustomQwtPlot 中(会自动分配颜色) curve->setSamples(vecXpt, vec);
plot->AddCurve(curve); 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::xBottom, 0, x.last());
// plot->setAxisScale(QwtPlot::yLeft,minValue , maxValue); // plot->setAxisScale(QwtPlot::yLeft,minValue , maxValue);
@ -275,7 +299,7 @@ void CountRateAnalysisView::onActionPlotConfigure()
layout->addLayout(btnLayout); layout->addLayout(btnLayout);
colorBtnList.append(colorBtn); 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 current = curveColorMap.value(curve);
QColor selected = QColorDialog::getColor(current, &dlg, QStringLiteral(u"选择曲线颜色")); QColor selected = QColorDialog::getColor(current, &dlg, QStringLiteral(u"选择曲线颜色"));
if (selected.isValid()) { if (selected.isValid()) {
@ -330,7 +354,80 @@ void CountRateAnalysisView::onActionPlotConfigure()
pen.setColor(curveColorMap.value(curve)); pen.setColor(curveColorMap.value(curve));
curve->setPen(pen); curve->setPen(pen);
} }
// 同步更新颜色缓存,确保后续重算时保持用户在图表配置中设置的颜色
if (!curveList.isEmpty()) {
m_curveColor = curveList.first()->pen().color();
}
// 刷新绘图 // 刷新绘图
plot->replot(); 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);
}
}
}

View File

@ -9,7 +9,7 @@
class CustomQwtPlot; class CustomQwtPlot;
class BusyIndicatorWidget; class BusyIndicatorWidget;
class QMenu; class QMenu;
class QwtPlotCurve;
namespace Ui { namespace Ui {
class CountRateAnalysisView; class CountRateAnalysisView;
} }
@ -39,11 +39,17 @@ private:
private slots: private slots:
void onActionPlotConfigure(); void onActionPlotConfigure();
void on_pushButton_clicked();
private: private:
Ui::CountRateAnalysisView *ui; Ui::CountRateAnalysisView *ui;
BusyIndicatorWidget* _busy_indicator = nullptr; BusyIndicatorWidget* _busy_indicator = nullptr;
CustomQwtPlot *plot; CustomQwtPlot *plot;
QMenu* _menu = nullptr; QMenu* _menu = nullptr;
QColor m_curveColor;
int m_statIntervalSec = 1; //计数率统计时间间隔(秒)
int m_peakEnergy = 45; // 特征峰能量KeV
QVector<ParticleInjectTime> m_rawData; // 原始粒子注入时间数据缓存,用于修改设置后重算
}; };
#endif //COUNTRATEANALYSIS_H #endif //COUNTRATEANALYSIS_H

View File

@ -172,8 +172,6 @@ void MainWindow::onMeasureStopped(bool success, const QString& message)
{ {
Q_UNUSED(message); Q_UNUSED(message);
if (success) { if (success) {
// ui->action_start_measure->setEnabled(true);
// ui->action_stop_measure->setEnabled(false);
m_AddressCountTimer->stop(); m_AddressCountTimer->stop();
m_EnergyCountTimer->stop(); m_EnergyCountTimer->stop();
LOG_INFO(message); 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<QString, QMap<QString, QStandardItem*> > all_nodes =
ProjectList::Instance()->getProjectNodeItems();
if (!all_nodes.contains(project_name))
return;
QMap<QString, QStandardItem*> 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();
}
} }
} }

View File

@ -865,6 +865,12 @@ void MeasureAnalysisProjectModelList::onChannelAddressCountProcessFinished(bool
auto adrr_count_spec_item = node_map[adrr_count_spec_item_name]; auto adrr_count_spec_item = node_map[adrr_count_spec_item_name];
this->SetNodeStatus(adrr_count_spec_item, status, status_ok); 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(); pro_model->SaveProjectModel();
if ( !pro_model->GetEnergyScaleFilename().isEmpty() ) { if ( !pro_model->GetEnergyScaleFilename().isEmpty() ) {