1、封装QwtPlot;2、添加关闭测量分析项目;3、补充提交遗漏提交源码文件

This commit is contained in:
徐海 2026-03-09 16:50:21 +08:00
parent 324c29cbbc
commit 34b78ac310
12 changed files with 423 additions and 120 deletions

31
src/AnalysisTypeDefine.h Normal file
View File

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

76
src/CustomQwtPlot.cpp Normal file
View File

@ -0,0 +1,76 @@
#include "CustomQwtPlot.h"
#include <QwtPlotCurve>
#include <QwtLegend>
#include <QwtPlotCanvas>
#include <QPen>
CustomQwtPlot::CustomQwtPlot(QWidget *parent)
: QwtPlot(parent)
{
}
const QList<QwtPlotCurve *> &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<int> base_hues = {
0, // 红色
30, // 橙色
60, // 黄色
90, // 黄绿色
120, // 绿色
150, // 青绿色
180, // 青色
210, // 天蓝色
240, // 蓝色
270, // 紫色
300, // 洋红色
330 // 玫红色
};
// 2. 定义不同的饱和度/明度组合(避免颜色太暗/太灰)
const QList<QPair<int, int>> 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;
}

23
src/CustomQwtPlot.h Normal file
View File

@ -0,0 +1,23 @@
#ifndef CUSTOMQWTPLOT_H
#define CUSTOMQWTPLOT_H
#include <QList>
#include <QwtPlot>
class QwtPlotCurve;
class CustomQwtPlot : public QwtPlot
{
public:
explicit CustomQwtPlot(QWidget* parent = nullptr);
const QList<QwtPlotCurve*>& GetCurveList() const;
void AddCurve(QwtPlotCurve* curve);
private:
QList<QwtPlotCurve*> _curves;
};
QColor getDistinctColorForManyCurves(int curve_index);
#endif // CUSTOMQWTPLOT_H

View File

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

View File

@ -1,79 +1,49 @@
#include "MeasureAnalysisParticleCountPlotView.h"
#include "CustomQwtPlot.h"
#include "csv.h"
#include <QVector>
#include <GlobalDefine.h>
#include <QHBoxLayout>
#include <QwtPlot>
#include <QwtPlotCurve>
#include <QPen>
#include <QRegularExpression>
#include <QVector>
#include <QwtLegend>
#include <QwtPlotCanvas>
#include <QPen>
QColor getDistinctColorForManyCurves(int curveIndex)
{
// 1. 定义基础色相覆盖不同主色系0-360度
const QList<int> baseHues = {
0, // 红色
30, // 橙色
60, // 黄色
90, // 黄绿色
120, // 绿色
150, // 青绿色
180, // 青色
210, // 天蓝色
240, // 蓝色
270, // 紫色
300, // 洋红色
330 // 玫红色
};
// 2. 定义不同的饱和度/明度组合(避免颜色太暗/太灰)
const QList<QPair<int, int>> 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 <QwtPlotCurve>
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<QString, QVariant> &data_files_set)
void MeasureAnalysisParticleCountPlotView::SetAnalyzeDataFilename(const QMap<QString, QVariant>& 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);
}

View File

@ -5,7 +5,7 @@
#include <QWidget>
#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

View File

@ -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<QString, QStandardItem*> 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<QString, QStandardItem*> 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<AnalysisType>()) {
_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<AnalysisType>()) {
_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<QString, QStandardItem*> 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));
}
}

View File

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

View File

@ -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<AnalysisType>();
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<QString, QVariant> 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<QString, QVariant> 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<QString, QVariant> 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;
}
}

View File

@ -0,0 +1,30 @@
#ifndef MEASUREANALYSISTREEVIEW_H
#define MEASUREANALYSISTREEVIEW_H
#include <QObject>
#include <QTreeView>
#include <QWidget>
#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<QStandardItem*, MeasureAnalysisView*> _item_views;
};
#endif // MEASUREANALYSISTREEVIEW_H

View File

@ -61,5 +61,5 @@ int main(int argc, char *argv[])
MainWindow w;
w.showMaximized();
return app.exec();
return app.exec();
}

View File

@ -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 \