diff --git a/src/AnalysisTypeDefine.h b/src/AnalysisTypeDefine.h new file mode 100644 index 0000000..af2e8ec --- /dev/null +++ b/src/AnalysisTypeDefine.h @@ -0,0 +1,31 @@ +#ifndef ANALYSISTYPEDEFINE_H +#define ANALYSISTYPEDEFINE_H + +enum class AnalysisType { + None, + Project, // 项目 + DeviceParamsCfg, // 设备参数配置 + EnergyScale, // 能量刻度 + EfficiencyScale, // 效率刻度 + ParticleData, // 粒子数据 + AddressCountData, // 粒子道址计数数据 + EnergyCountData, // 能量计数数据 + ChannelEnergyCountData, // 通道能量计数数据 + CoincidenceParticleEnergyData, // 符合粒子能量数据 + AddressCountSpectrumView, // 粒子计数谱视图 + EneryCountSpectrumView, // 能量计数谱视图 + CoincidenceParticleEnergySpectrum2DView, // 符合粒子能量2D视图 + CoincidenceParticleEnergySpectrum3DView, // 符合粒子能量3D视图 + CountingRateView, // 计数率视图 + EnergyPeakFitView, // 能量峰拟合视图 + NuclideAnalysisView, // 核分析视图 + ParticleInTimeView, // 粒子在时间视图 + ParticleTimeDiffView, // 粒子时间差视图 + CoincidenceEventTimeView, // 符合事件时间视图 + CoincidenceParticleEnergySpectrumView, // 符合粒子能量谱视图 + AntiCoincidenceSpectrumView // 反符合粒子能量谱视图 +}; + +Q_DECLARE_METATYPE(AnalysisType) + +#endif // ANALYSISTYPEDEFINE_H diff --git a/src/CustomQwtPlot.cpp b/src/CustomQwtPlot.cpp new file mode 100644 index 0000000..41b6173 --- /dev/null +++ b/src/CustomQwtPlot.cpp @@ -0,0 +1,76 @@ +#include "CustomQwtPlot.h" +#include +#include +#include +#include + +CustomQwtPlot::CustomQwtPlot(QWidget *parent) + : QwtPlot(parent) +{ + +} + +const QList &CustomQwtPlot::GetCurveList() const +{ + return _curves; +} + +void CustomQwtPlot::AddCurve(QwtPlotCurve *curve) +{ + if (curve) { + curve->setPen(QPen(getDistinctColorForManyCurves(_curves.count()))); + curve->attach(this); + _curves.append(curve); + } +} + +QColor getDistinctColorForManyCurves(int curve_index) +{ + // 1. 定义基础色相(覆盖不同主色系,0-360度) + const QList base_hues = { + 0, // 红色 + 30, // 橙色 + 60, // 黄色 + 90, // 黄绿色 + 120, // 绿色 + 150, // 青绿色 + 180, // 青色 + 210, // 天蓝色 + 240, // 蓝色 + 270, // 紫色 + 300, // 洋红色 + 330 // 玫红色 + }; + + // 2. 定义不同的饱和度/明度组合(避免颜色太暗/太灰) + const QList> sv_combinations = { + {85, 90}, // 高饱和、高明度 + {70, 85}, // 中高饱和、中高明度 + {85, 75}, // 高饱和、中明度 + {60, 80}, // 中饱和、中高明度 + {75, 70}, // 中高饱和、中明度 + {90, 80} // 极高饱和、中高明度 + }; + + // 3. 计算当前曲线对应的色相和饱和度/明度 + int hue_index = curve_index % base_hues.size(); // 循环使用基础色相 + int sv_index = (curve_index / base_hues.size()) % sv_combinations.size(); // 循环使用饱和度/明度组合 + + // 4. 获取HSV参数(色相0-360,饱和度0-255,明度0-255) + int hue = base_hues[hue_index]; + int saturation = sv_combinations[sv_index].first * 255 / 100; // 转换为0-255范围 + int value = sv_combinations[sv_index].second * 255 / 100; // 转换为0-255范围 + + // 5. 生成并返回颜色(HSV转RGB) + QColor color; + color.setHsv(hue, saturation, value); + + // 额外优化:避免极浅/极暗的颜色(保证曲线可见) + if (value < 50 * 255 / 100) { + value = 50 * 255 / 100; + color.setHsv(hue, saturation, value); + } + + return color; +} + diff --git a/src/CustomQwtPlot.h b/src/CustomQwtPlot.h new file mode 100644 index 0000000..7af592c --- /dev/null +++ b/src/CustomQwtPlot.h @@ -0,0 +1,23 @@ +#ifndef CUSTOMQWTPLOT_H +#define CUSTOMQWTPLOT_H + +#include +#include + +class QwtPlotCurve; + +class CustomQwtPlot : public QwtPlot +{ +public: + explicit CustomQwtPlot(QWidget* parent = nullptr); + + const QList& GetCurveList() const; + void AddCurve(QwtPlotCurve* curve); + +private: + QList _curves; +}; + +QColor getDistinctColorForManyCurves(int curve_index); + +#endif // CUSTOMQWTPLOT_H diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp index 19367d1..c5143ff 100644 --- a/src/MainWindow.cpp +++ b/src/MainWindow.cpp @@ -201,11 +201,19 @@ void MainWindow::initAction() } } }); - connect(ui->action_close_measurement_analysis, &QAction::triggered, this, [](){ + connect(ui->action_close_measurement_analysis, &QAction::triggered, this, [this](){ MeasureAnalysisProjectModel* project_model = ProjectList::Instance()->GetCurrentProjectModel(); if (project_model) { - + const QString& project_name = project_model->GetProjectName(); + const QString& title = QStringLiteral(u"关闭测量分析项目"); + const QString& text = QStringLiteral(u"是否关闭测量分析项目\"%1\"").arg(project_name); + auto result = QMessageBox::question(this, title, text, QMessageBox::Yes | QMessageBox::No); + if (QMessageBox::Yes == result) { + project_model->SaveProjectModel(); + ProjectList::Instance()->RmProjectModel(project_name); + } } + }); connect(ui->action_manage_measurement_analysis, &QAction::triggered, this->_action_central_dock_widget, &QAction::triggered); connect(ui->action_device_config_mrg, &QAction::triggered, this, []() { diff --git a/src/MeasureAnalysisParticleCountPlotView.cpp b/src/MeasureAnalysisParticleCountPlotView.cpp index ca92fbb..5485d01 100644 --- a/src/MeasureAnalysisParticleCountPlotView.cpp +++ b/src/MeasureAnalysisParticleCountPlotView.cpp @@ -1,79 +1,49 @@ #include "MeasureAnalysisParticleCountPlotView.h" +#include "CustomQwtPlot.h" #include "csv.h" -#include #include #include -#include -#include +#include +#include +#include #include #include -#include - -QColor getDistinctColorForManyCurves(int curveIndex) -{ - // 1. 定义基础色相(覆盖不同主色系,0-360度) - const QList baseHues = { - 0, // 红色 - 30, // 橙色 - 60, // 黄色 - 90, // 黄绿色 - 120, // 绿色 - 150, // 青绿色 - 180, // 青色 - 210, // 天蓝色 - 240, // 蓝色 - 270, // 紫色 - 300, // 洋红色 - 330 // 玫红色 - }; - - // 2. 定义不同的饱和度/明度组合(避免颜色太暗/太灰) - const QList> sVCombinations = { - {85, 90}, // 高饱和、高明度 - {70, 85}, // 中高饱和、中高明度 - {85, 75}, // 高饱和、中明度 - {60, 80}, // 中饱和、中高明度 - {75, 70}, // 中高饱和、中明度 - {90, 80} // 极高饱和、中高明度 - }; - - // 3. 计算当前曲线对应的色相和饱和度/明度 - int hueIndex = curveIndex % baseHues.size(); // 循环使用基础色相 - int svIndex = (curveIndex / baseHues.size()) % sVCombinations.size(); // 循环使用饱和度/明度组合 - - // 4. 获取HSV参数(色相0-360,饱和度0-255,明度0-255) - int hue = baseHues[hueIndex]; - int saturation = sVCombinations[svIndex].first * 255 / 100; // 转换为0-255范围 - int value = sVCombinations[svIndex].second * 255 / 100; // 转换为0-255范围 - - // 5. 生成并返回颜色(HSV转RGB) - QColor color; - color.setHsv(hue, saturation, value); - - // 额外优化:避免极浅/极暗的颜色(保证曲线可见) - if (value < 50 * 255 / 100) { - value = 50 * 255 / 100; - color.setHsv(hue, saturation, value); - } - - return color; -} +#include MeasureAnalysisParticleCountPlotView::MeasureAnalysisParticleCountPlotView(QWidget* parent) : MeasureAnalysisView { parent } { this->setViewType(PlotFrame); + QHBoxLayout* layout = new QHBoxLayout(this); - _plot = new QwtPlot(this); + _plot = new CustomQwtPlot(this); layout->addWidget(_plot); setupPlot(); } -void MeasureAnalysisParticleCountPlotView::SetAnalyzeDataFilename(const QMap &data_files_set) +void MeasureAnalysisParticleCountPlotView::SetAnalyzeDataFilename(const QMap& data_files_set) { - for (auto it = data_files_set.begin(); it != data_files_set.end(); ++it) { - loadDataFromFile(it.key(), it.value().toString()); + auto extractNumber = [](const QString& str) { + int ret_num = 0; + QRegularExpression regex("\\d+"); + QRegularExpressionMatch match = regex.match(str); + if (match.hasMatch()) { + ret_num = match.captured().toInt(); + } + return ret_num; + }; + QStringList ch_count_data_name = data_files_set.keys(); + std::sort(ch_count_data_name.begin(), ch_count_data_name.end(), [extractNumber](const QString& a, const QString& b) { + int num_a = extractNumber(a); + int num_b = extractNumber(b); + return num_a < num_b; + }); + for (const QString& ch_count_data_name : ch_count_data_name) { + if (ch_count_data_name.contains(ch_count_data_name)) { + const QString ch_count_data_filename = data_files_set[ch_count_data_name].toString(); + loadDataFromFile(ch_count_data_name, ch_count_data_filename); + } } } @@ -95,8 +65,8 @@ void MeasureAnalysisParticleCountPlotView::setupPlot() _plot->enableAxis(QwtPlot::yLeft); // 设置QWT图例 - QwtLegend *legend = new QwtLegend(); - legend->setDefaultItemMode(QwtLegendData::Clickable); + QwtLegend* legend = new QwtLegend(); + legend->setDefaultItemMode(QwtLegendData::Checkable); _plot->insertLegend(legend, QwtPlot::RightLegend); } @@ -104,14 +74,14 @@ void MeasureAnalysisParticleCountPlotView::loadDataFromFile(const QString& data_ { std::string address_str = QString(QStringLiteral(u"道址")).toStdString(); std::string count_str = QString(QStringLiteral(u"计数")).toStdString(); - + io::CSVReader< 2, io::trim_chars<' ', '\t'>, io::double_quote_escape<',', '"'>, io::throw_on_overflow, - io::empty_line_comment - > reader(QStrToSysPath(filename)); + io::empty_line_comment> + reader(QStrToSysPath(filename)); reader.read_header(io::ignore_extra_column, address_str, count_str); int address; @@ -124,7 +94,7 @@ void MeasureAnalysisParticleCountPlotView::loadDataFromFile(const QString& data_ // 绘制曲线 QwtPlotCurve* curve = new QwtPlotCurve(data_name); - curve->setPen(QPen(getDistinctColorForManyCurves(0))); curve->setSamples(x, y); - curve->attach(_plot); + _plot->AddCurve(curve); + LOG_DEBUG(data_name); } diff --git a/src/MeasureAnalysisParticleCountPlotView.h b/src/MeasureAnalysisParticleCountPlotView.h index 88ff90d..68ffbbd 100644 --- a/src/MeasureAnalysisParticleCountPlotView.h +++ b/src/MeasureAnalysisParticleCountPlotView.h @@ -5,7 +5,7 @@ #include #include "MeasureAnalysisView.h" -class QwtPlot; +class CustomQwtPlot; class MeasureAnalysisParticleCountPlotView : public MeasureAnalysisView { @@ -20,7 +20,7 @@ private: void loadDataFromFile(const QString &data_name, const QString& filename); private: - QwtPlot* _plot { nullptr }; + CustomQwtPlot* _plot { nullptr }; }; #endif // MEASUREANALYSISPARTICLECOUNTPLOTVIEW_H diff --git a/src/MeasureAnalysisProjectModel.cpp b/src/MeasureAnalysisProjectModel.cpp index 8cad2e0..3ba2e0a 100644 --- a/src/MeasureAnalysisProjectModel.cpp +++ b/src/MeasureAnalysisProjectModel.cpp @@ -426,20 +426,48 @@ MeasureAnalysisProjectModelList* MeasureAnalysisProjectModelList::Instance() return _s_instance; } +MeasureAnalysisProjectModelList::~MeasureAnalysisProjectModelList() +{ + const auto& models_list = _project_models.values(); + for (auto it=models_list.constBegin(); it!=models_list.constEnd(); ++it) { + auto& model = *it; + model->SaveProjectModel(); + } +} + void MeasureAnalysisProjectModelList::AddProjectModel(MeasureAnalysisProjectModel* model) { const QString& project_name = model->GetProjectName(); _project_models[project_name] = model; + intiProjectNodeStruce(model); SetCurrentProjectModel(project_name); - intiProjectNodeStruce(); + model->SaveProjectModel(); } void MeasureAnalysisProjectModelList::RmProjectModel(const QString& project_name) { + if (!_project_node_items.contains(project_name)) { + return; + } + const QMap item_nodes = _project_node_items[project_name]; + if (!item_nodes.contains(project_name) ) { + return; + } + QStandardItem* project_item = item_nodes[project_name]; + if (project_item) { + this->RemoveNode(project_item); + } if (_project_models.contains(project_name)) { delete _project_models[project_name]; _project_models.remove(project_name); } + const auto& project_model = _project_models.first(); + if (project_model) { + const QString& project_name = project_model->GetProjectName(); + SetCurrentProjectModel(project_name); + } + const QString& info_text = QStringLiteral(u"测试分析项\"%1\"已关闭.").arg(project_name); + LOG_INFO(info_text); } MeasureAnalysisProjectModel* MeasureAnalysisProjectModelList::GetProjectModel(const QString& project_name) @@ -461,14 +489,19 @@ void MeasureAnalysisProjectModelList::SetCurrentProjectModel(const QString& proj _current_project_model = _project_models[project_name]; for (auto it = _project_node_items.constBegin(); it!=_project_node_items.constEnd(); ++it) { - QStandardItem* project_item = it.value(); - QFont font = project_item->font(); - if ( it.key() == project_name ) { - font.setBold(true); - } else { - font.setBold(false); + const QMap item_nodes = it.value(); + if ( item_nodes.contains(project_name) ) { + QStandardItem* project_item = item_nodes[project_name]; + if (project_item) { + QFont font = project_item->font(); + if ( it.key() == project_name ) { + font.setBold(true); + } else { + font.setBold(false); + } + project_item->setFont(font); + } } - project_item->setFont(font); } } } @@ -514,26 +547,23 @@ bool MeasureAnalysisProjectModelList::RemoveNode(QStandardItem* item) return false; if (item->column() == NameColumn && item->data(Fixed).toBool()) return false; - + const QString& project_name = item->data(ProjectName).toString(); + if (AnalysisType::Project == item->data(NodeType).value()) { + _project_node_items.remove(project_name); + delete item; + return true; + } QStandardItem* parent_item = item->parent(); if (!parent_item) { return false; } parent_item->removeRow(item->row()); - - const QString& project_name = item->data(ProjectName).toString(); - if (AnalysisType::Project == item->data(NodeType).value()) { - _project_node_items.remove(project_name); - return true; - } else { - const QString& node_name = item->text(); - if (_project_node_items.contains(project_name)) { - if (_project_node_items[project_name].contains(node_name)) { - _project_node_items[project_name].remove(node_name); - } + const QString& node_name = item->text(); + if (_project_node_items.contains(project_name)) { + if (_project_node_items[project_name].contains(node_name)) { + _project_node_items[project_name].remove(node_name); } } - return true; } @@ -603,21 +633,22 @@ void MeasureAnalysisProjectModelList::onChannelAddressCountProcessFinished(const auto adrr_count_spec_item = node_map[adrr_count_spec_item_name]; this->SetNodeStatus(adrr_count_spec_item, status); } + + pro_model->SaveProjectModel(); } } -void MeasureAnalysisProjectModelList::intiProjectNodeStruce() +void MeasureAnalysisProjectModelList::intiProjectNodeStruce(MeasureAnalysisProjectModel* pro_model) { - MeasureAnalysisProjectModel* cur_pro_model = GetCurrentProjectModel(); - if (!cur_pro_model) { + if (!pro_model) { return; } QMap node_map; QStandardItem* root_item = invisibleRootItem(); - const QString& project_name = cur_pro_model->GetProjectName(); - QString status = cur_pro_model->GetIsMeasureComplete() ? QStringLiteral(u"测量完成") : QStringLiteral(u"未测量"); + const QString& project_name = pro_model->GetProjectName(); + QString status = pro_model->GetIsMeasureComplete() ? QStringLiteral(u"测量完成") : QStringLiteral(u"未测量"); QVariant analys_type = QVariant::fromValue(AnalysisType::Project); QStandardItem* project_item = AddChildNode(root_item, project_name, status, analys_type, false); project_item->setData(project_name, ProjectName); @@ -629,8 +660,8 @@ void MeasureAnalysisProjectModelList::intiProjectNodeStruce() measure_ctrl_item->setData(project_name, ProjectName); node_map[item_name] = measure_ctrl_item; - if (!cur_pro_model->GetIsMeasureComplete()) { - const QString& measure_device_params_cfg_filename = cur_pro_model->GetMeasureDeviceParamsCfgFilename(); + if (!pro_model->GetIsMeasureComplete()) { + const QString& measure_device_params_cfg_filename = pro_model->GetMeasureDeviceParamsCfgFilename(); status = measure_device_params_cfg_filename.isEmpty() ? QStringLiteral(u"未配置") : QStringLiteral(u"已配置"); analys_type = QVariant::fromValue(AnalysisType::DeviceParamsCfg); item_name = QStringLiteral(u"设备配置参数"); @@ -639,14 +670,14 @@ void MeasureAnalysisProjectModelList::intiProjectNodeStruce() node_map[item_name] = node_item; } - status = cur_pro_model->GetEneryScaleFilename().isEmpty() ? QStringLiteral(u"未配置") : QStringLiteral(u"已配置"); + status = pro_model->GetEneryScaleFilename().isEmpty() ? QStringLiteral(u"未配置") : QStringLiteral(u"已配置"); analys_type = QVariant::fromValue(AnalysisType::EnergyScale); item_name = QStringLiteral(u"能量刻度"); QStandardItem* node_item = AddChildNode(measure_ctrl_item, item_name, status, analys_type, true); node_item->setData(project_name, ProjectName); node_map[item_name] = node_item; - status = cur_pro_model->GetEfficiencyScaleFilename().isEmpty() ? QStringLiteral(u"未配置") : QStringLiteral(u"已配置"); + status = pro_model->GetEfficiencyScaleFilename().isEmpty() ? QStringLiteral(u"未配置") : QStringLiteral(u"已配置"); analys_type = QVariant::fromValue(AnalysisType::EfficiencyScale); item_name = QStringLiteral(u"效率刻度"); node_item = AddChildNode(measure_ctrl_item, item_name, status, analys_type, true); @@ -659,7 +690,7 @@ void MeasureAnalysisProjectModelList::intiProjectNodeStruce() analysis_data_item->setData(project_name, ProjectName); node_map[item_name] = node_item; - status = cur_pro_model->GetAllChannelParticleDataFilename().isEmpty() ? QStringLiteral(u"无效") : QStringLiteral(u"有效"); + status = pro_model->GetAllChannelParticleDataFilename().isEmpty() ? QStringLiteral(u"无效") : QStringLiteral(u"有效"); analys_type = QVariant::fromValue(AnalysisType::ParticleData); item_name = QStringLiteral(u"测量粒子数据"); node_item = AddChildNode(analysis_data_item, item_name, status, analys_type, true); @@ -667,7 +698,7 @@ void MeasureAnalysisProjectModelList::intiProjectNodeStruce() node_map[item_name] = node_item; item_name = QStringLiteral(u"道址计数"); - const auto& ch_addr_count_data_filename_list = cur_pro_model->GetChannelAddressCountDataFilenameList(); + const auto& ch_addr_count_data_filename_list = pro_model->GetChannelAddressCountDataFilenameList(); status = ch_addr_count_data_filename_list.isEmpty() ? QStringLiteral(u"无效") : QStringLiteral(u"有效"); node_item = AddChildNode(analysis_data_item, item_name, status, QVariant(), true); node_item->setData(project_name, ProjectName); @@ -684,13 +715,13 @@ void MeasureAnalysisProjectModelList::intiProjectNodeStruce() } item_name = QStringLiteral(u"能量计数"); - status = cur_pro_model->GetAllChannelEneryTotalCountDataFilename().isEmpty() ? QStringLiteral(u"无效") : QStringLiteral(u"有效"); + status = pro_model->GetAllChannelEneryTotalCountDataFilename().isEmpty() ? QStringLiteral(u"无效") : QStringLiteral(u"有效"); analys_type = QVariant::fromValue(AnalysisType::EnergyCountData); node_item = AddChildNode(analysis_data_item, item_name, status, analys_type, true); node_item->setData(project_name, ProjectName); node_map[item_name] = node_item; QStandardItem* enery_count_item = node_item; - const auto& ch_enery_count_data_filename_list = cur_pro_model->GetChannelEneryCountDataFilenameList(); + const auto& ch_enery_count_data_filename_list = pro_model->GetChannelEneryCountDataFilenameList(); for (auto it = ch_enery_count_data_filename_list.begin(); it != ch_enery_count_data_filename_list.end(); ++it) { uint ch_num = it.key(); QString item_name = QStringLiteral(u"通道%1能量计数").arg(ch_num); @@ -701,8 +732,8 @@ void MeasureAnalysisProjectModelList::intiProjectNodeStruce() node_map[item_name] = node_item; } - uint conform_time_win = cur_pro_model->GetConformTimeWin(); - status = cur_pro_model->GetTimeWinConformParticleDataFilenameList(conform_time_win).isEmpty() ? QStringLiteral(u"无效") : QStringLiteral(u"有效"); + uint conform_time_win = pro_model->GetConformTimeWin(); + status = pro_model->GetTimeWinConformParticleDataFilenameList(conform_time_win).isEmpty() ? QStringLiteral(u"无效") : QStringLiteral(u"有效"); analys_type = QVariant::fromValue(AnalysisType::CoincidenceParticleEnergyData); item_name = QStringLiteral(u"符合粒子数据[%1ns]").arg(conform_time_win); node_item = AddChildNode(analysis_data_item, item_name, status, analys_type, true); @@ -715,63 +746,63 @@ void MeasureAnalysisProjectModelList::intiProjectNodeStruce() interactive_analysis_item->setData(project_name, ProjectName); node_map[item_name] = interactive_analysis_item; - status = cur_pro_model->GetChannelAddressCountDataFilenameList().isEmpty() ? QStringLiteral(u"无效") : QStringLiteral(u"有效"); + status = pro_model->GetChannelAddressCountDataFilenameList().isEmpty() ? QStringLiteral(u"无效") : QStringLiteral(u"有效"); analys_type = QVariant::fromValue(AnalysisType::AddressCountSpectrumView); item_name = QStringLiteral(u"道址计数谱"); node_item = AddChildNode(interactive_analysis_item, item_name, status, analys_type, true); node_item->setData(project_name, ProjectName); node_map[item_name] = node_item; - status = cur_pro_model->GetChannelEneryCountDataFilenameList().isEmpty() ? QStringLiteral(u"无效") : QStringLiteral(u"有效"); + status = pro_model->GetChannelEneryCountDataFilenameList().isEmpty() ? QStringLiteral(u"无效") : QStringLiteral(u"有效"); analys_type = QVariant::fromValue(AnalysisType::EneryCountSpectrumView); item_name = QStringLiteral(u"通道能量计数谱"); node_item = AddChildNode(interactive_analysis_item, item_name, status, analys_type, true); node_item->setData(project_name, ProjectName); node_map[item_name] = node_item; - status = cur_pro_model->GetAllChannelEneryTotalCountDataFilename().isEmpty() ? QStringLiteral(u"无效") : QStringLiteral(u"有效"); + status = pro_model->GetAllChannelEneryTotalCountDataFilename().isEmpty() ? QStringLiteral(u"无效") : QStringLiteral(u"有效"); analys_type = QVariant::fromValue(AnalysisType::EneryCountSpectrumView); item_name = QStringLiteral(u"能量计数谱"); node_item = AddChildNode(interactive_analysis_item, item_name, status, analys_type, true); node_item->setData(project_name, ProjectName); node_map[item_name] = node_item; - status = cur_pro_model->GetSortAllChannelParticleDataFilename().isEmpty() ? QStringLiteral(u"无效") : QStringLiteral(u"有效"); + status = pro_model->GetSortAllChannelParticleDataFilename().isEmpty() ? QStringLiteral(u"无效") : QStringLiteral(u"有效"); analys_type = QVariant::fromValue(AnalysisType::CountingRateView); item_name = QStringLiteral(u"计数率分析"); node_item = AddChildNode(interactive_analysis_item, item_name, status, analys_type, true); node_item->setData(project_name, ProjectName); node_map[item_name] = node_item; - status = cur_pro_model->GetAllChannelEneryTotalCountDataFilename().isEmpty() ? QStringLiteral(u"无效") : QStringLiteral(u"有效"); + status = pro_model->GetAllChannelEneryTotalCountDataFilename().isEmpty() ? QStringLiteral(u"无效") : QStringLiteral(u"有效"); analys_type = QVariant::fromValue(AnalysisType::EnergyPeakFitView); item_name = QStringLiteral(u"峰拟合分析"); node_item = AddChildNode(interactive_analysis_item, item_name, status, analys_type, true); node_item->setData(project_name, ProjectName); node_map[item_name] = node_item; - status = cur_pro_model->GetAllChannelEneryTotalCountDataFilename().isEmpty() ? QStringLiteral(u"无效") : QStringLiteral(u"有效"); + status = pro_model->GetAllChannelEneryTotalCountDataFilename().isEmpty() ? QStringLiteral(u"无效") : QStringLiteral(u"有效"); analys_type = QVariant::fromValue(AnalysisType::NuclideAnalysisView); item_name = QStringLiteral(u"核素分析"); node_item = AddChildNode(interactive_analysis_item, item_name, status, analys_type, true); node_item->setData(project_name, ProjectName); node_map[item_name] = node_item; - status = cur_pro_model->GetSortAllChannelParticleDataFilename().isEmpty() ? QStringLiteral(u"无效") : QStringLiteral(u"有效"); + status = pro_model->GetSortAllChannelParticleDataFilename().isEmpty() ? QStringLiteral(u"无效") : QStringLiteral(u"有效"); analys_type = QVariant::fromValue(AnalysisType::ParticleInTimeView); item_name = QStringLiteral(u"粒子入射时间分析"); node_item = AddChildNode(interactive_analysis_item, item_name, status, analys_type, true); node_item->setData(project_name, ProjectName); node_map[item_name] = node_item; - status = cur_pro_model->GetSortAllChannelParticleDataFilename().isEmpty() ? QStringLiteral(u"无效") : QStringLiteral(u"有效"); + status = pro_model->GetSortAllChannelParticleDataFilename().isEmpty() ? QStringLiteral(u"无效") : QStringLiteral(u"有效"); analys_type = QVariant::fromValue(AnalysisType::ParticleTimeDiffView); item_name = QStringLiteral(u"粒子时间差分析"); node_item = AddChildNode(interactive_analysis_item, item_name, status, analys_type, true); node_item->setData(project_name, ProjectName); node_map[item_name] = node_item; - status = cur_pro_model->GetTimeWinConformParticleDataFilenameList(conform_time_win).isEmpty() ? QStringLiteral(u"无效") : QStringLiteral(u"有效"); + status = pro_model->GetTimeWinConformParticleDataFilenameList(conform_time_win).isEmpty() ? QStringLiteral(u"无效") : QStringLiteral(u"有效"); analys_type = QVariant::fromValue(AnalysisType::CoincidenceEventTimeView); item_name = QStringLiteral(u"符合事件时间分析"); node_item = AddChildNode(interactive_analysis_item, item_name, status, analys_type, true); @@ -805,15 +836,15 @@ void MeasureAnalysisProjectModelList::intiProjectNodeStruce() _project_node_items[project_name] = node_map; LOG_INFO(QStringLiteral(u"测量分析项目\"%1\"创建成功.").arg(project_name)); - if (!cur_pro_model->GetIsMeasureComplete()) { - if (cur_pro_model->GetMeasureDeviceParamsCfgFilename().isEmpty()) { + if (!pro_model->GetIsMeasureComplete()) { + if (pro_model->GetMeasureDeviceParamsCfgFilename().isEmpty()) { LOG_WARN(QStringLiteral(u"测量分析项目\"%1\"测量设备参数未配置!").arg(project_name)); } } - if (cur_pro_model->GetEneryScaleFilename().isEmpty()) { + if (pro_model->GetEneryScaleFilename().isEmpty()) { LOG_WARN(QStringLiteral(u"测量分析项目\"%1\"能量刻度未配置!").arg(project_name)); } - if (cur_pro_model->GetEfficiencyScaleFilename().isEmpty()) { + if (pro_model->GetEfficiencyScaleFilename().isEmpty()) { LOG_WARN(QStringLiteral(u"测量分析项目\"%1\"效率刻度未配置!").arg(project_name)); } } diff --git a/src/MeasureAnalysisProjectModel.h b/src/MeasureAnalysisProjectModel.h index bb85f09..28b347d 100644 --- a/src/MeasureAnalysisProjectModel.h +++ b/src/MeasureAnalysisProjectModel.h @@ -118,6 +118,7 @@ public: public: static MeasureAnalysisProjectModelList* Instance(); + virtual ~MeasureAnalysisProjectModelList(); void AddProjectModel(MeasureAnalysisProjectModel* model); void RmProjectModel(const QString& project_name); @@ -143,7 +144,7 @@ private slots: void onChannelAddressCountProcessFinished(const QString& project_name); private: - void intiProjectNodeStruce(); + void intiProjectNodeStruce(MeasureAnalysisProjectModel *pro_model); private: explicit MeasureAnalysisProjectModelList(QObject *parent = nullptr); diff --git a/src/MeasureAnalysisTreeView.cpp b/src/MeasureAnalysisTreeView.cpp new file mode 100644 index 0000000..ff0c176 --- /dev/null +++ b/src/MeasureAnalysisTreeView.cpp @@ -0,0 +1,131 @@ +#include "MeasureAnalysisTreeView.h" +#include "AnalysisTypeDefine.h" +#include "QHeaderView" +#include "MeasureAnalysisView.h" + +MeasureAnalysisTreeView::MeasureAnalysisTreeView(QWidget* parent) + : QTreeView(parent) +{ + _model = ProjectList::Instance(); + this->setModel(_model); + + QHeaderView* header_view = header(); + header_view->setSectionResizeMode(QHeaderView::Interactive); + header_view->setMinimumSectionSize(10); + header_view->resizeSection(1, 20); + + this->setEditTriggers(NoEditTriggers); + this->setSelectionBehavior(SelectRows); + this->setSelectionMode(SingleSelection); + + setContextMenuPolicy(Qt::CustomContextMenu); + connect(this, &QTreeView::customContextMenuRequested, this, &MeasureAnalysisTreeView::onCustomContextMenuRequested); + + connect(this, &QTreeView::doubleClicked, this, &MeasureAnalysisTreeView::onNodeDoubleClicked); +} + +void MeasureAnalysisTreeView::onCustomContextMenuRequested(const QPoint& pos) +{ + QModelIndex index = indexAt(pos); + if (!index.isValid()) + return; + + QStandardItem* item = _model->GetItemFromIndex(index); + if (!item) + return; + + QVariant user_data = _model->GetNodeUserData(item); +} + +void MeasureAnalysisTreeView::onNodeDoubleClicked(const QModelIndex& index) +{ + if (!index.isValid()) + return; + QStandardItem* item = _model->GetItemFromIndex(index); + if (!item) + return; + const QString& item_text = item->text(); + QVariant project_name_data = _model->GetNodeUserData(item, ProjectList::ProjectName); + if (!project_name_data.isValid()) + return; + QString project_name = project_name_data.toString(); + QVariant analysis_type_data = _model->GetNodeUserData(item, ProjectList::NodeType); + if (!analysis_type_data.isValid()) + return; + AnalysisType analysis_type = analysis_type_data.value(); + + switch(analysis_type) { + case AnalysisType::ParticleData: { + MeasureAnalysisProjectModel* project_model = _model->GetProjectModel(project_name); + if (project_model) { + auto file_name = project_model->GetAllChannelParticleDataFilename(); + if ( !file_name.isEmpty() ) { + QMap data_files_set; + data_files_set[QStringLiteral(u"粒子数据")] = file_name; + MeasureAnalysisView* view = MeasureAnalysisView::NewAnalyzeView(analysis_type); + if ( view ) { + const auto& view_name = QStringLiteral(u"%1 [%2]").arg(item_text).arg(project_name); + view->SetViewName(view_name); + view->SetViewDescription(view_name); + view->SetAnalyzeDataFilename(data_files_set); + emit currentItemView(view); + } + } + } + } break; + case AnalysisType::AddressCountData: { + QVariant ch_num_data = _model->GetNodeUserData(item, ProjectList::ChannelNum); + if (ch_num_data.isValid()) { + int ch_num = ch_num_data.toInt(); + MeasureAnalysisProjectModel* project_model = _model->GetProjectModel(project_name); + if (project_model) { + auto file_name = project_model->GetChannelAddressCountDataFilename(ch_num); + if ( !file_name.isEmpty() ) { + QMap data_files_set; + data_files_set[QStringLiteral(u"通道%1道址计数").arg(ch_num)] = file_name; + MeasureAnalysisView* view = MeasureAnalysisView::NewAnalyzeView(analysis_type); + if ( view ) { + const auto& view_name = QStringLiteral(u"%1 [%2]").arg(item_text).arg(project_name); + view->SetViewName(view_name); + view->SetViewDescription(view_name); + view->SetAnalyzeDataFilename(data_files_set); + emit currentItemView(view); + } + } + } + } + } break; + case AnalysisType::AddressCountSpectrumView: { + MeasureAnalysisProjectModel* project_model = _model->GetProjectModel(project_name); + if (project_model) { + auto file_name_list = project_model->GetChannelAddressCountDataFilenameList(); + if ( !file_name_list.isEmpty() ) { + QMap data_files_set; + auto ch_num_list = file_name_list.keys(); + for(auto ch_num : ch_num_list) { + auto file_name = file_name_list[ch_num]; + if ( !file_name.isEmpty() ) { + data_files_set[QStringLiteral(u"通道%1道址计数").arg(ch_num)] = file_name; + } + } + MeasureAnalysisView* view = nullptr; + if ( _item_views.contains(item) ) { + view = _item_views[item]; + } else { + view = MeasureAnalysisView::NewAnalyzeView(analysis_type); + const auto& view_name = QStringLiteral(u"%1 [%2]").arg(item_text).arg(project_name); + view->SetViewName(view_name); + view->SetViewDescription(view_name); + view->SetAnalyzeDataFilename(data_files_set); + } + if ( view ) { + _item_views[item] = view; + emit currentItemView(view); + } + } + } + } break; + default: + break; + } +} diff --git a/src/MeasureAnalysisTreeView.h b/src/MeasureAnalysisTreeView.h new file mode 100644 index 0000000..84841c7 --- /dev/null +++ b/src/MeasureAnalysisTreeView.h @@ -0,0 +1,30 @@ +#ifndef MEASUREANALYSISTREEVIEW_H +#define MEASUREANALYSISTREEVIEW_H + +#include +#include +#include +#include "MeasureAnalysisProjectModel.h" + +class MeasureAnalysisView; + +class MeasureAnalysisTreeView : public QTreeView +{ + Q_OBJECT +public: + explicit MeasureAnalysisTreeView(QWidget *parent = nullptr); + +private slots: + void onCustomContextMenuRequested(const QPoint &pos); + void onNodeDoubleClicked(const QModelIndex &index); + +signals: + void currentItemView(MeasureAnalysisView* view); + void removeItemView(MeasureAnalysisView* view); + +private: + ProjectList* _model; + QMap _item_views; +}; + +#endif // MEASUREANALYSISTREEVIEW_H diff --git a/src/main.cpp b/src/main.cpp index 6629dd3..10ae752 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -61,5 +61,5 @@ int main(int argc, char *argv[]) MainWindow w; w.showMaximized(); - return app.exec(); + return app.exec(); } diff --git a/src/src.pro b/src/src.pro index 707916a..a67937f 100644 --- a/src/src.pro +++ b/src/src.pro @@ -30,6 +30,7 @@ UI_DIR = $${BUILD_UI}/$${TARGET}/ui SOURCES += \ AboutDlg.cpp \ + CustomQwtPlot.cpp \ DataProcessWorkPool.cpp \ EneryScaleForm.cpp \ MainWindow.cpp \ @@ -50,6 +51,7 @@ SOURCES += \ HEADERS += \ AboutDlg.h \ AnalysisTypeDefine.h \ + CustomQwtPlot.h \ DataProcessWorkPool.h \ EneryScaleForm.h \ GlobalDefine.h \