修改点击停止后,树不更新,解决点击树节点奔溃问题。解决树节点重复问题

This commit is contained in:
anxinglong 2026-07-30 17:52:23 +08:00
parent 78304ac19a
commit 944b2d2444
5 changed files with 185 additions and 55 deletions

View File

@ -154,13 +154,22 @@ void CountRateAnalysisView::setData(QVector<ParticleInjectTime> data)
QVector<ParticleInjectTime> CountRateAnalysisView::getParticleInjectTimeData(QString path)
{
QVector<ParticleInjectTime> 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<ParticleInjectTime> 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;
}

View File

@ -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);

View File

@ -191,7 +191,6 @@ void MainWindow::onMeasureStopped(bool success, const QString& message)
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))
@ -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)) {

View File

@ -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()) {

View File

@ -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<double> x;
QVector<double> 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<double> x;
QVector<double> 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<double> x;
// QVector<double> 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()