diff --git a/src/CountRateAnalysisView/CountRateAnalysisView.cpp b/src/CountRateAnalysisView/CountRateAnalysisView.cpp index 6297a94..8d43cf4 100644 --- a/src/CountRateAnalysisView/CountRateAnalysisView.cpp +++ b/src/CountRateAnalysisView/CountRateAnalysisView.cpp @@ -154,13 +154,22 @@ void CountRateAnalysisView::setData(QVector data) QVector CountRateAnalysisView::getParticleInjectTimeData(QString path) { QVector records; + QFile file(path); + if (!file.exists()) { + qWarning() << "[CountRateAnalysisView] 数据文件不存在:" << path; + return records; + } + if (file.size() == 0) { + qWarning() << "[CountRateAnalysisView] 数据文件为空:" << path; + return records; + } io::CSVReader<4> in(QStrToSysPath(path)); in.read_header(io::ignore_extra_column, "板卡号", "通道号", "能量(KeV)", "时间计数"); int board, channel; double energy, time_count; int lineNumber = 0; - + try { // 逐行读取 while (in.read_row(board, channel, energy, time_count)) { @@ -176,7 +185,11 @@ QVector CountRateAnalysisView::getParticleInjectTimeData(QSt rec.dTime = time_count; records.append(rec); } - + } catch (const std::exception& e) { + qWarning() << "[CountRateAnalysisView] CSV读取异常:" << e.what(); + } catch (...) { + qWarning() << "[CountRateAnalysisView] CSV读取未知异常"; + } return records; } diff --git a/src/EfficiencyScale.cpp b/src/EfficiencyScale.cpp index 02f7d5b..474399e 100644 --- a/src/EfficiencyScale.cpp +++ b/src/EfficiencyScale.cpp @@ -49,8 +49,6 @@ EfficiencyScale::EfficiencyScale(QWidget *parent) _fitCurve->attach(_plot); ui->table_scale_data->verticalHeader()->hide(); initComboBoxUi(); - - // 初始化32个通道数据 for (int i = 1; i <= 32; ++i) { QString channelName = QStringLiteral(u"通道%1").arg(i); diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp index 9f30432..6ce01fe 100644 --- a/src/MainWindow.cpp +++ b/src/MainWindow.cpp @@ -191,7 +191,6 @@ void MainWindow::onMeasureStopped(bool success, const QString& message) const QString& project_name = pro_model->GetProjectName(); - // 从 ProjectList 获取项目的所有节点(比 nodeMap 更可靠) QMap > all_nodes = ProjectList::Instance()->getProjectNodeItems(); if (!all_nodes.contains(project_name)) @@ -201,21 +200,17 @@ void MainWindow::onMeasureStopped(bool success, const QString& message) 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(); @@ -233,6 +228,20 @@ void MainWindow::onMeasureStopped(bool success, const QString& message) count_task->StartTask(); } + QStringList analysis_nodes; + analysis_nodes << QStringLiteral(u"计数率分析") + << QStringLiteral(u"峰拟合分析") + << QStringLiteral(u"核素分析") + << QStringLiteral(u"粒子入射时间分析"); + bool analysis_status_ok = !pro_model->GetParticleEnergyDataFilename().isEmpty(); + QString analysis_status = analysis_status_ok ? QStringLiteral(u"有效") : QStringLiteral(u"无效"); + for (const QString &node_name : analysis_nodes) { + QStandardItem *analysis_item = project_nodes[node_name]; + if (analysis_item) { + ProjectList::Instance()->SetNodeStatus(analysis_item, analysis_status, analysis_status_ok); + } + } + if (!all_channel_particle_data_filename.isEmpty()) { auto coincidence_task = new DataProcessWorkPool::CoincidenceEventAnalysisTask; coincidence_task->SetFinishedNotifier( @@ -515,9 +524,6 @@ void MainWindow::closeProject(const QString& project_name) } } - - - void MainWindow::showEvent(QShowEvent *event) { QMainWindow::showEvent(event); @@ -925,7 +931,6 @@ void MainWindow::onParticleEnergyDataUpdated(const QString &energySpectrumFilena // 更新项目模型 project_model->SetParticleEnergyDataFilename(energySpectrumFilename); project_model->SaveProjectModel(); - // 更新节点状态 const QString &energy_node_name = QStringLiteral(u"粒子能量数据"); if (nodeMap.contains(energy_node_name)) { diff --git a/src/MeasureAnalysisProjectModel.cpp b/src/MeasureAnalysisProjectModel.cpp index 9a16494..10a2202 100644 --- a/src/MeasureAnalysisProjectModel.cpp +++ b/src/MeasureAnalysisProjectModel.cpp @@ -853,11 +853,35 @@ void MeasureAnalysisProjectModelList::onChannelAddressCountProcessFinished(bool for (auto it = filename_list.begin(); it != filename_list.end(); ++it) { uint ch_num = it.key(); QString item_name = QStringLiteral(u"通道%1道址计数").arg(ch_num); - const QVariant& analys_type = QVariant::fromValue(AnalysisType::AddressCountData); - QStandardItem* node_item = AddChildNode(adrr_count_item, item_name, status, analys_type, true, status_ok); - node_item->setData(project_name, ProjectName); - node_item->setData(ch_num, ChannelNum); - node_map[item_name] = node_item; + + // 新增:先遍历UI子节点,检查是否已有同名节点 + QStandardItem* existing_item = nullptr; + for (int i = 0; i < adrr_count_item->rowCount(); ++i) { + QStandardItem* child = adrr_count_item->child(i); + if (child && child->text() == item_name) { + existing_item = child; + break; + } + } + + if (existing_item) { + // 已存在 → 只更新状态,同步映射表 + this->SetNodeStatus(existing_item, status, status_ok); + node_map[item_name] = existing_item; + } else { + // 不存在 → 才创建新节点 + const QVariant& analys_type = QVariant::fromValue(AnalysisType::AddressCountData); + QStandardItem* node_item = AddChildNode(adrr_count_item, item_name, status, analys_type, true, status_ok); + node_item->setData(project_name, ProjectName); + node_item->setData(ch_num, ChannelNum); + node_map[item_name] = node_item; + } + // QString item_name = QStringLiteral(u"通道%1道址计数").arg(ch_num); + // const QVariant& analys_type = QVariant::fromValue(AnalysisType::AddressCountData); + // QStandardItem* node_item = AddChildNode(adrr_count_item, item_name, status, analys_type, true, status_ok); + // node_item->setData(project_name, ProjectName); + // node_item->setData(ch_num, ChannelNum); + // node_map[item_name] = node_item; } } const QString& adrr_count_spec_item_name = QStringLiteral(u"道址计数谱"); @@ -950,16 +974,37 @@ void MeasureAnalysisProjectModelList::onEnergyCountProcessFinished(bool ok, cons for (auto it = channel_energy_count_filename_list.constBegin(); it != channel_energy_count_filename_list.constEnd(); ++it) { uint ch_num = it.key(); QString item_name = QStringLiteral(u"通道%1能量计数").arg(ch_num); - if ( !node_map.contains(item_name) ) { + QStandardItem* existing_item = nullptr; + for (int i = 0; i < energy_total_count_item->rowCount(); ++i) { + QStandardItem* child = energy_total_count_item->child(i); + if (child && child->text() == item_name) { + existing_item = child; + break; + } + } + + if (existing_item) { + // 已存在 → 只更新状态,同步映射表 + this->SetNodeStatus(existing_item, status, status_ok); + node_map[item_name] = existing_item; + } else { + // 不存在 → 才创建新节点 const QVariant& analys_type = QVariant::fromValue(AnalysisType::EnergyCountData); QStandardItem* node_item = AddChildNode(energy_total_count_item, item_name, status, analys_type, true, status_ok); node_item->setData(project_name, ProjectName); node_item->setData(ch_num, ChannelNum); node_map[item_name] = node_item; - } else { - auto ch_energy_count_item = node_map[item_name]; - this->SetNodeStatus(ch_energy_count_item, status, status_ok); } + // if ( !node_map.contains(item_name) ) { + // const QVariant& analys_type = QVariant::fromValue(AnalysisType::EnergyCountData); + // QStandardItem* node_item = AddChildNode(energy_total_count_item, item_name, status, analys_type, true, status_ok); + // node_item->setData(project_name, ProjectName); + // node_item->setData(ch_num, ChannelNum); + // node_map[item_name] = node_item; + // } else { + // auto ch_energy_count_item = node_map[item_name]; + // this->SetNodeStatus(ch_energy_count_item, status, status_ok); + // } } const auto& ch_energy_count_data_list = pro_model->GetChannelEnergyCountDataFilenameList(); if (!ch_energy_count_data_list.isEmpty()) { diff --git a/src/ParticleInjectTimeView/ParticleInjectTimeAnalysisView.cpp b/src/ParticleInjectTimeView/ParticleInjectTimeAnalysisView.cpp index 01496a7..bd2a2a6 100644 --- a/src/ParticleInjectTimeView/ParticleInjectTimeAnalysisView.cpp +++ b/src/ParticleInjectTimeView/ParticleInjectTimeAnalysisView.cpp @@ -117,48 +117,117 @@ void ParticleInjectTimeAnalysisView::setupMenu() void ParticleInjectTimeAnalysisView::updateData(bool b_init_update) { _busy_indicator->Start(); - auto functionToRun = [this, b_init_update](){ - if(!_data_filename.isEmpty()) { - std::string board_id_str = QString(QStringLiteral(u"板卡号")).toStdString(); - std::string channel_id_str = QString(QStringLiteral(u"通道号")).toStdString(); - std::string energy_str = QString(QStringLiteral(u"能量(KeV)")).toStdString(); - std::string time_str = QString(QStringLiteral(u"时间计数")).toStdString(); + QString data_filename = _data_filename; - io::CSVReader<4> in(QStrToSysPath(_data_filename)); - in.read_header(io::ignore_extra_column, board_id_str, channel_id_str, energy_str, time_str); - - int particle_num = 0; - QVector x; - QVector y; - - int board, channel; - double energy; - unsigned long long time_count; - double x_max = 0.0f, y_max = 0.0f; - while (in.read_row(board, channel, energy, time_count)) { - if ( !b_init_update && (energy <= _begin_enery || energy >= _end_energy)) { - continue; + auto functionToRun = [this, b_init_update,data_filename](){ + if(data_filename.isEmpty()) { + QMetaObject::invokeMethod(this, [this]() { + if (_busy_indicator) { + _busy_indicator->Stop(); } - particle_num++; - x.append(particle_num); - y.append(time_count); - if ( x_max < particle_num ) - x_max = particle_num; - if ( y_max < time_count ) - y_max = time_count; + }, Qt::QueuedConnection); + return; + } + try { + std::string board_id_str = QString(QStringLiteral(u"板卡号")).toStdString(); + std::string channel_id_str = QString(QStringLiteral(u"通道号")).toStdString(); + std::string energy_str = QString(QStringLiteral(u"能量(KeV)")).toStdString(); + std::string time_str = QString(QStringLiteral(u"时间计数")).toStdString(); + + io::CSVReader<4> in(QStrToSysPath(data_filename)); + in.read_header(io::ignore_extra_column, board_id_str, channel_id_str, energy_str, time_str); + + int particle_num = 0; + QVector x; + QVector y; + + int board, channel; + double energy; + unsigned long long time_count; + double x_max = 0.0f, y_max = 0.0f; + while (in.read_row(board, channel, energy, time_count)) { + if ( !b_init_update && (energy <= _begin_enery || energy >= _end_energy)) { + continue; } - QMetaObject::invokeMethod(this, [this, x_max, y_max, x, y]() { - _plot->SetAxisInitRange(QwtPlot::xBottom, 0.0f, x_max); - _plot->SetAxisInitRange(QwtPlot::yLeft, 0.0f, y_max); - _curve->setSamples(x, y); - _plot->replot(); - // LOG_INFO(QStringLiteral(u"[%1]例子时间差数据加载完毕.").arg(this->GetProjectName()).arg(this->GetViewName())); + particle_num++; + x.append(particle_num); + y.append(time_count); + if ( x_max < particle_num ) + x_max = particle_num; + if ( y_max < time_count ) + y_max = time_count; + } + + QMetaObject::invokeMethod(this, [this, x_max, y_max, x, y]() { + if (!this || !_plot || !_curve) return; + _plot->SetAxisInitRange(QwtPlot::xBottom, 0.0f, x_max); + _plot->SetAxisInitRange(QwtPlot::yLeft, 0.0f, y_max); + _curve->setSamples(x, y); + _plot->replot(); + if (_busy_indicator) { _busy_indicator->Stop(); + } + }, Qt::QueuedConnection); + } catch (const std::exception& e) { + qWarning() << "[ParticleInjectTimeAnalysisView] CSV读取异常:" << e.what(); + QMetaObject::invokeMethod(this, [this]() { + if (_busy_indicator) { + _busy_indicator->Stop(); + } + }, Qt::QueuedConnection); + } catch (...) { + qWarning() << "[ParticleInjectTimeAnalysisView] CSV读取未知异常"; + QMetaObject::invokeMethod(this, [this]() { + if (_busy_indicator) { + _busy_indicator->Stop(); + } }, Qt::QueuedConnection); } }; QThread* load_data_thread = QThread::create(functionToRun); + connect(load_data_thread, &QThread::finished, load_data_thread, &QThread::deleteLater); // 线程结束自动删除 load_data_thread->start(); + // if(!_data_filename.isEmpty()) { + // std::string board_id_str = QString(QStringLiteral(u"板卡号")).toStdString(); + // std::string channel_id_str = QString(QStringLiteral(u"通道号")).toStdString(); + // std::string energy_str = QString(QStringLiteral(u"能量(KeV)")).toStdString(); + // std::string time_str = QString(QStringLiteral(u"时间计数")).toStdString(); + + // io::CSVReader<4> in(QStrToSysPath(_data_filename)); + // in.read_header(io::ignore_extra_column, board_id_str, channel_id_str, energy_str, time_str); + + // int particle_num = 0; + // QVector x; + // QVector y; + + // int board, channel; + // double energy; + // unsigned long long time_count; + // double x_max = 0.0f, y_max = 0.0f; + // while (in.read_row(board, channel, energy, time_count)) { + // if ( !b_init_update && (energy <= _begin_enery || energy >= _end_energy)) { + // continue; + // } + // particle_num++; + // x.append(particle_num); + // y.append(time_count); + // if ( x_max < particle_num ) + // x_max = particle_num; + // if ( y_max < time_count ) + // y_max = time_count; + // } + // QMetaObject::invokeMethod(this, [this, x_max, y_max, x, y]() { + // _plot->SetAxisInitRange(QwtPlot::xBottom, 0.0f, x_max); + // _plot->SetAxisInitRange(QwtPlot::yLeft, 0.0f, y_max); + // _curve->setSamples(x, y); + // _plot->replot(); + // // LOG_INFO(QStringLiteral(u"[%1]例子时间差数据加载完毕.").arg(this->GetProjectName()).arg(this->GetViewName())); + // _busy_indicator->Stop(); + // }, Qt::QueuedConnection); + // } + // }; + // QThread* load_data_thread = QThread::create(functionToRun); + // load_data_thread->start(); } void ParticleInjectTimeAnalysisView::onActionPlotConfigure()