diff --git a/bin/theme.rcc b/bin/theme.rcc index 86132d2..6ea8fb0 100644 Binary files a/bin/theme.rcc and b/bin/theme.rcc differ diff --git a/src/AntiConformEnergySpectrumView/AntiConformEnergySpectrumView.cpp b/src/AntiConformEnergySpectrumView/AntiConformEnergySpectrumView.cpp new file mode 100644 index 0000000..21696bd --- /dev/null +++ b/src/AntiConformEnergySpectrumView/AntiConformEnergySpectrumView.cpp @@ -0,0 +1,158 @@ +#include "AntiConformEnergySpectrumView.h" +#include +#include +#include +#include +#include "CustomQwtPlot.h" +#include +#include "csv.h" +#include +#include +#include "BusyIndicator.h" +#include +#include +#include +#include +#include +struct SpectrumData +{ + int board_id; + int channel_id; + double energy; + uint64_t timestamp; +}; + + +AntiConformEnergySpectrumView::AntiConformEnergySpectrumView(QWidget *parent) : + MeasureAnalysisView(parent) +{ + this->setViewType(PlotFrame); + + _plot = new CustomQwtPlot(); + QVBoxLayout* layout = new QVBoxLayout(this); + layout->addWidget(_plot); + + _plot->setCanvasBackground(Qt::white); + QwtPlotCanvas* canvas = qobject_cast(_plot->canvas()); + canvas->setFrameStyle(QFrame::NoFrame); + + QFont font = this->font(); + font.setBold(false); + QwtText x_label = QStringLiteral(u"能量(KeV)"); + QwtText y_label = QStringLiteral(u"反符合事件次数"); + x_label.setFont(font); + y_label.setFont(font); + _plot->setAxisTitle(QwtPlot::xBottom, x_label); + _plot->setAxisTitle(QwtPlot::yLeft, y_label); + + _plot->setAxisAutoScale(QwtPlot::xBottom, true); + _plot->setAxisAutoScale(QwtPlot::yLeft, true); + _plot->enableAxis(QwtPlot::xBottom); + _plot->enableAxis(QwtPlot::yLeft); + _plot->SetAxisDragScale(QwtPlot::xBottom, true); + + _curve = new QwtPlotCurve(); + _curve->setStyle(QwtPlotCurve::Lines); + _curve->setPen(QPen(QColor(23, 229, 238), 2)); + _plot->AddCurve(_curve); + + _busy_indicator = new BusyIndicator(this); +} + +AntiConformEnergySpectrumView::~AntiConformEnergySpectrumView() +{ +} + +void AntiConformEnergySpectrumView::InitViewWorkspace(const QString &project_name) +{ + Q_UNUSED(project_name); +} + +void AntiConformEnergySpectrumView::SetAnalyzeDataFilename(const QMap &data_files_set) +{ + const QString& data_filename = data_files_set.first().toString(); + if (!data_filename.isEmpty() && QFileInfo(data_filename).exists()) { + this->_data_filename = data_filename; + this->loadAndProcess(); + } +} + + +void AntiConformEnergySpectrumView::loadAndProcess() +{ + auto functionToRun = [this]() { + if (_data_filename.isEmpty()) return; + + _busy_indicator->Start(); + + std::vector rawData; + io::CSVReader<4> in(QStrToSysPath(_data_filename)); + in.read_header(io::ignore_extra_column, + QString(QStringLiteral(u"板卡号")).toStdString(), + QString(QStringLiteral(u"通道号")).toStdString(), + QString(QStringLiteral(u"能量(KeV)")).toStdString(), + QString(QStringLiteral(u"时间计数")).toStdString()); + + int board, channel; + double energy; + unsigned long long time_count; + while (in.read_row(board, channel, energy, time_count)) { + SpectrumData sd; + sd.board_id = board; + sd.channel_id = channel; + sd.energy = energy; + sd.timestamp = time_count; + rawData.push_back(sd); + } + + if (rawData.empty()) { + _busy_indicator->Stop(); + return; + } + + const int STEP = 1; + std::map hist; + + for (const auto& spdt : rawData) { + int idx = static_cast(spdt.energy) / STEP; + hist[idx] += 1.0; + } + + QVector vx, vy; + for (const auto& pair : hist) { + vx.push_back(pair.first * STEP); + vy.push_back(pair.second); + } + + if (vx.isEmpty()) { + _busy_indicator->Stop(); + return; + } + + double dmaxx = *std::max_element(vx.begin(), vx.end()); + double dmaxy = *std::max_element(vy.begin(), vy.end()); + + QMetaObject::invokeMethod(this, [this, vx, vy, dmaxx, dmaxy]() { + _curve->setSamples(vx, vy); + + _plot->setAxisScale(QwtPlot::xBottom, 0, dmaxx); + _plot->setAxisScale(QwtPlot::yLeft, 0, dmaxy * 1.1); + _plot->replot(); + _busy_indicator->Stop(); + }, Qt::QueuedConnection); + }; + + QThread* load_thread = QThread::create(functionToRun); + load_thread->start(); +} + +void AntiConformEnergySpectrumView::showEvent(QShowEvent *e) +{ + Q_UNUSED(e); + if (_busy_indicator) { + _busy_indicator->setGeometry(this->rect()); + this->update(); + } +} + + diff --git a/src/AntiConformEnergySpectrumView/AntiConformEnergySpectrumView.h b/src/AntiConformEnergySpectrumView/AntiConformEnergySpectrumView.h new file mode 100644 index 0000000..80d1b57 --- /dev/null +++ b/src/AntiConformEnergySpectrumView/AntiConformEnergySpectrumView.h @@ -0,0 +1,34 @@ +#ifndef ANTICONFORMENERGYSPECTRUMVIEW_H +#define ANTICONFORMENERGYSPECTRUMVIEW_H + +#include "MeasureAnalysisView.h" + +class CustomQwtPlot; +class QwtPlotCurve; +class BusyIndicator; + +class AntiConformEnergySpectrumView : public MeasureAnalysisView +{ + Q_OBJECT +public: + explicit AntiConformEnergySpectrumView(QWidget *parent = nullptr); + virtual ~AntiConformEnergySpectrumView(); + virtual void InitViewWorkspace(const QString& project_name) override final; + virtual void SetAnalyzeDataFilename(const QMap& data_files_set) override; + +protected: + virtual void showEvent(QShowEvent* e) override final; + +private: + void loadAndProcess(); // 读取CSV,执行符合处理,绘制能谱折线图 + +private: + BusyIndicator* _busy_indicator = nullptr; + CustomQwtPlot* _plot = nullptr; + QwtPlotCurve* _curve = nullptr; + QString _data_filename; +}; + +#endif // ANTICONFORMENERGYSPECTRUMVIEW_H + + diff --git a/src/CustomQwtPlot.h b/src/CustomQwtPlot.h index 0e59954..46e1650 100644 --- a/src/CustomQwtPlot.h +++ b/src/CustomQwtPlot.h @@ -106,9 +106,6 @@ private: }; - - - QColor getDistinctColorForManyCurves(int curve_index); #endif // CUSTOMQWTPLOT_H diff --git a/src/DataCalcProcess/AdaptiveSimpsonIntegrate.h b/src/DataCalcProcess/AdaptiveSimpsonIntegrate.h index bbf9b33..aae617c 100644 --- a/src/DataCalcProcess/AdaptiveSimpsonIntegrate.h +++ b/src/DataCalcProcess/AdaptiveSimpsonIntegrate.h @@ -1,13 +1,14 @@ #ifndef ADAPTIVESIMPSONINTEGRATE_H #define ADAPTIVESIMPSONINTEGRATE_H -namespace AdaptiveSimpsonIntegrate { - #include #include #include //#include + +namespace AdaptiveSimpsonIntegrate { + // 定义被积函数:y = A*exp(-(x-P)²/(2*delt²)) + H/(1+exp((x-P)/W)) + C struct FitFunction { // 拟合公式的参数 @@ -55,7 +56,7 @@ double adaptive_simpson(double a, double b, double eps, const Func& f, double right = simpson(c, b, f); // 精度判断:满足则返回,不满足则递归细分 - if (::std::abs(left + right - whole) <= 15 * eps) { + if (std::abs(left + right - whole) <= 15 * eps) { return left + right + (left + right - whole) / 15.0; } diff --git a/src/DataCalcProcess/CoincidenceSpectrum.cpp b/src/DataCalcProcess/CoincidenceSpectrumProcess.cpp similarity index 87% rename from src/DataCalcProcess/CoincidenceSpectrum.cpp rename to src/DataCalcProcess/CoincidenceSpectrumProcess.cpp index b90051c..8dd87ee 100644 --- a/src/DataCalcProcess/CoincidenceSpectrum.cpp +++ b/src/DataCalcProcess/CoincidenceSpectrumProcess.cpp @@ -178,6 +178,7 @@ void SortDataByTimestamp(std::vector& data) bool ProcessCoincidence( std::vector& data, std::vector& events, + std::vector& anti_coincidence_events, unsigned int time_window, int min_order, int max_order @@ -187,8 +188,13 @@ bool ProcessCoincidence( if (n < min_order) { return false; } + if (min_order < 2 || max_order < min_order) + return false; + std::vector is_used(n, false); // 使用滑动窗口寻找符合事件 for (int i = 0; i < n; ++i) { + if (is_used[i]) + continue; std::vector current_coincidence; current_coincidence.push_back(data[i]); // 寻找时间窗口内的其他事件 @@ -206,6 +212,10 @@ bool ProcessCoincidence( // 保存符合条件的事件 int coincidence_order = current_coincidence.size(); if (coincidence_order >= min_order && coincidence_order <= max_order) { + // 标记这些事件已被使用 + for (int k = 0; k < coincidence_order; ++k) { + is_used[i + k] = true; + } CoincidenceEvent result; result.coincidence_order = coincidence_order; result.events = current_coincidence; @@ -213,6 +223,31 @@ bool ProcessCoincidence( events.push_back(result); } } + + for (int i = 0; i < n; ++i) { + if (is_used[i]) + continue; + bool is_anti = true; + // 检查前向时间窗口内是否有其他事件 + if (i > 0) { + unsigned long long diff_prev = data[i].timestamp - data[i-1].timestamp; + if (diff_prev <= time_window) + is_anti = false; + } + // 检查后向时间窗口内是否有其他事件 + if (i < n-1 && is_anti) { + unsigned long long diff_next = data[i+1].timestamp - data[i].timestamp; + if (diff_next <= time_window) + is_anti = false; + } + // 满足反符合条件 + if (is_anti) { + AntiCoincidenceEvent res; + res.event = data[i]; + res.time_window = time_window; + anti_coincidence_events.push_back(res); + } + } return true; } diff --git a/src/DataCalcProcess/CoincidenceSpectrumProcess.h b/src/DataCalcProcess/CoincidenceSpectrumProcess.h index fafa651..f172e70 100644 --- a/src/DataCalcProcess/CoincidenceSpectrumProcess.h +++ b/src/DataCalcProcess/CoincidenceSpectrumProcess.h @@ -28,6 +28,11 @@ namespace F2t9Order { std::vector events; // 符合的事件集合 unsigned int time_window; // 使用的时间窗口(秒) }; + // 反符合事件结构体(只包含未参与任何符合的独立事件) + struct AntiCoincidenceEvent { + SpectrumData event; // 反符合单事件 + unsigned int time_window; // 时间窗口 + }; // 读取CSV数据文件 std::vector ReadCsv(const std::string& filename); @@ -39,6 +44,7 @@ namespace F2t9Order { bool ProcessCoincidence( std::vector &data, std::vector &events, + std::vector& anti_coincidence_events, unsigned int time_window, // 时间窗口(纳秒) int min_order = 2, // 最小符合次数 int max_order = 9 // 最大符合次数 diff --git a/src/DataCalcProcess/DataCalcProcess.pri b/src/DataCalcProcess/DataCalcProcess.pri index 02bd660..336dd76 100644 --- a/src/DataCalcProcess/DataCalcProcess.pri +++ b/src/DataCalcProcess/DataCalcProcess.pri @@ -6,7 +6,7 @@ LIBS += -L$$PWD/armadillo/lib -llibblas LIBS += -L$$PWD/armadillo/lib -lliblapack SOURCES += \ - $$PWD/CoincidenceSpectrum.cpp \ + $$PWD/CoincidenceSpectrumProcess.cpp \ $$PWD/EnergyEfficiencyFit.cpp \ $$PWD/Poly2FindPeaks.cpp \ $$PWD/FindPeaksBySvd.cpp \ diff --git a/src/DataProcessWorkPool.cpp b/src/DataProcessWorkPool.cpp index d7bbb85..18238af 100644 --- a/src/DataProcessWorkPool.cpp +++ b/src/DataProcessWorkPool.cpp @@ -466,6 +466,7 @@ bool CoincidenceEventAnalysisTask::processTask() if (particle_data_filename.isEmpty()) { return false; } + std::string time_win_str = QString(QStringLiteral(u"时间窗口")).toStdString(); std::string event_id_str = QString(QStringLiteral(u"事件ID")).toStdString(); std::string board_id_str = QString(QStringLiteral(u"板卡号")).toStdString(); std::string channel_id_str = QString(QStringLiteral(u"通道号")).toStdString(); @@ -490,8 +491,9 @@ bool CoincidenceEventAnalysisTask::processTask() spec_data_item.timestamp)) { spec_data.push_back(spec_data_item); } - std::vector events; - if (!ProcessCoincidence(spec_data, events, project_model->GetConformTimeWin())) { + std::vector coincidence_events; + std::vector anti_coincidence_events; + if (!ProcessCoincidence(spec_data, coincidence_events, anti_coincidence_events, project_model->GetConformTimeWin())) { LOG_WARN(QStringLiteral(u"粒子符合数据处理异常!")); } const QString& coincidence_data_dir_name = QStringLiteral(u"粒子符合数据"); @@ -500,7 +502,7 @@ bool CoincidenceEventAnalysisTask::processTask() const QString& coincidence_data_dir_path = project_dir.filePath(coincidence_data_dir_name); QMap > coincidence_data_out_stream_map; unsigned long long event_id = 0; - for (const CoincidenceEvent& event : events) { + for (const CoincidenceEvent& event : coincidence_events) { ++ event_id; const QString& event_data_filename = QDir(coincidence_data_dir_path).filePath(QStringLiteral(u"[%1ns]%2个粒子符合事件[未刻度].csv").arg(project_model->GetConformTimeWin()).arg(event.coincidence_order)); if ( !coincidence_data_out_stream_map.contains(event.coincidence_order) ) { @@ -514,6 +516,13 @@ bool CoincidenceEventAnalysisTask::processTask() } project_model->SetTimeWinConformParticleData(project_model->GetConformTimeWin(), event.coincidence_order, event_data_filename); } + const QString& anti_event_data_filename = QDir(coincidence_data_dir_path).filePath(QStringLiteral(u"反符合事件[未刻度].csv")); + std::ofstream anti_event_data_out_stream(QStrToSysPath(anti_event_data_filename)); + anti_event_data_out_stream << time_win_str << "," << board_id_str << "," << channel_id_str << "," << addr_str << "," << time_str << std::endl; + for (const AntiCoincidenceEvent& anti_event : anti_coincidence_events) { + anti_event_data_out_stream << anti_event.time_window << "," << anti_event.event.board_id << "," << anti_event.event.channel_id << "," << anti_event.event.energy << "," << anti_event.event.timestamp << std::endl; + } + project_model->SetAntiConformParticleData(project_model->GetConformTimeWin(), anti_event_data_filename); } catch (const std::exception& e) { const QString& e_what = QString::fromUtf8(e.what()); LOG_WARN(QStringLiteral(u"粒子符合数据处理异常:%1").arg(e_what)); @@ -931,7 +940,83 @@ bool EnergyScaleCoincidenceDataTask::processTask() conformParticleDataEnergyScale(time_win, coincidence_order, conform_particle_data_filename); } } + const QString& info = QStringLiteral(u"符合能谱数据处理完成."); LOG_INFO(info); return true; } + +bool EnergyScaleaAntiCoincidenceDataTask::processTask() +{ + const QString& project_name = GetProjectName(); + MeasureAnalysisProjectModel* project_model = ProjectList::Instance()->GetProjectModel(project_name); + if (project_model == nullptr) { + return false; + } + EnergyScaleDataModel energy_scale_data_model(project_model->GetEnergyScaleFilename()); + if (!energy_scale_data_model.LoadData()) { + return false; + } + if (!energy_scale_data_model.IsValid()) { + return false; + } + const QString& coincidence_data_dir_name = QStringLiteral(u"符合能谱数据"); + QDir project_dir(project_model->GetProjectDir()); + project_dir.mkpath(coincidence_data_dir_name); + const QString& coincidence_data_dir_path = project_dir.filePath(coincidence_data_dir_name); + + std::string time_win_str = QString(QStringLiteral(u"时间窗口")).toStdString(); + std::string board_id_str = QString(QStringLiteral(u"板卡号")).toStdString(); + std::string channel_id_str = QString(QStringLiteral(u"通道号")).toStdString(); + std::string addr_str = QString(QStringLiteral(u"道址")).toStdString(); + std::string energy_str = QString(QStringLiteral(u"能量(KeV)")).toStdString(); + std::string time_str = QString(QStringLiteral(u"时间计数")).toStdString(); + + const auto& anti_conform_particle_data = project_model->GetAntiConformParticleData(); + for (const auto& time_win : anti_conform_particle_data.keys()) { + const auto&anti_conform_particle_data_filename = anti_conform_particle_data.value(time_win); + try { + io::CSVReader< + 5, + io::trim_chars<' ', '\t'>, + io::double_quote_escape<',', '"'>, + io::throw_on_overflow, + io::empty_line_comment> + reader(QStrToSysPath(anti_conform_particle_data_filename)); + reader.read_header(io::ignore_extra_column, time_win_str, board_id_str, channel_id_str, addr_str, time_str); + + const QString& anti_coincidence_energy_data_filename = QDir(coincidence_data_dir_path).filePath(QStringLiteral(u"反符合粒子事件.csv")); + std::ofstream out_stream(QStrToSysPath(anti_coincidence_energy_data_filename)); + out_stream << time_win_str << "," << board_id_str << "," << channel_id_str << "," << energy_str << "," << time_str << "\n" ; + using namespace CoincidenceSpectrum::F2t9Order; + unsigned int time_window; + SpectrumData data_item; + while (reader.read_row( + time_window, + data_item.board_id, + data_item.channel_id, + data_item.energy, + data_item.timestamp)) { + int channel_num = (data_item.board_id) * 4 + (data_item.channel_id + 1); + const QString& channel_name = QStringLiteral(u"通道%1").arg(channel_num); + auto coeffs = energy_scale_data_model.GetEnergyFitResultCoeffs(channel_name); + if (!coeffs.empty()) { + data_item.energy = GaussPolyCoe::Predict(coeffs, data_item.energy); + out_stream << time_window << "," << data_item.board_id << "," << data_item.channel_id << "," << data_item.energy << "," << data_item.timestamp << "\n" ; + } else { + LOG_WARN(QStringLiteral(u"符合能谱数据处理异常:%1能量刻度拟合参数为空!").arg(channel_name)); + } + } + out_stream.close(); + project_model->SetAntiConformEnergyData(time_win, anti_coincidence_energy_data_filename); + } catch (const std::exception& e) { + const QString& e_what = QString::fromStdString(e.what()); + LOG_WARN(QStringLiteral(u"反符合能谱数据处理异常:%1").arg(e_what)); + return false; + } + } + + const QString& info = QStringLiteral(u"反符合能谱数据处理完成."); + LOG_INFO(info); + return true; +} diff --git a/src/DataProcessWorkPool.h b/src/DataProcessWorkPool.h index e2e6bd5..a5bfb03 100644 --- a/src/DataProcessWorkPool.h +++ b/src/DataProcessWorkPool.h @@ -143,6 +143,12 @@ namespace DataProcessWorkPool private: virtual bool processTask() override; }; + + class EnergyScaleaAntiCoincidenceDataTask : public DataProcessTask + { + private: + virtual bool processTask() override; + }; } #endif // DATAPROCESSWORKPOOL_H diff --git a/src/DeviceParameterConfig/DeviceConfigView.cpp b/src/DeviceParameterConfig/DeviceConfigView.cpp deleted file mode 100644 index 50593a1..0000000 --- a/src/DeviceParameterConfig/DeviceConfigView.cpp +++ /dev/null @@ -1,463 +0,0 @@ -#include "DeviceConfigView.h" -#include "DeviceParameterProxy.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -class DeviceConfigViewModel: public QStandardItemModel -{ -public: - DeviceConfigViewModel(QObject *parent = nullptr) : QStandardItemModel(parent){} - virtual Qt::ItemFlags flags(const QModelIndex &index) const { - Qt::ItemFlags f = QStandardItemModel::flags(index); - if ( index.column() == 0 ) { - f = f & Qt::ItemIsUserCheckable; - } - return f; - } -}; - -DeviceConfigView::DeviceConfigView(QWidget *parent) - : MeasureAnalysisView(parent) - , m_tableView(nullptr) - , m_model(nullptr) -{ - initTableView(); -} - -DeviceConfigView::~DeviceConfigView() -{ -} - -void DeviceConfigView::initTableView() -{ - QVBoxLayout *layout = new QVBoxLayout(this); - layout->setContentsMargins(0, 0, 0, 0); - - m_tableView = new QTableView(this); - layout->addWidget(m_tableView); - - // 设置表头 - QStringList headList; - headList << tr("数据传输模式") << tr("硬件增益") << tr("硬件增益选择索引") - << tr("软件增益") << tr("时间常数") << tr("成形时间") << tr("快通道触发阈值") - << tr("多道分辨率") << tr("控制功能") << tr("幅度提前延迟") << tr("积分长度") - << tr("dcfd缩放倍数") << tr("dcfd延迟") << tr("直流偏移") << tr("最大能量范围") - << tr("Am 峰面积寻峰法的面积比例") << tr("K40与 Am241的峰位校正系数") << tr("高压关断阈值") - << tr("获取能谱周期") << tr("总测量时间") << tr("总测量次数") << tr("滤波参数") - << tr("上升时间") << tr("平顶时间") << tr("ICR 校正使能") << tr("CRZA 值") - << tr("ZA 使能值") << tr("操作"); - - m_model = new DeviceConfigViewModel(this); - m_model->setColumnCount(headList.size()); - m_model->setHorizontalHeaderLabels(headList); - m_model->setRowCount(32); - - for (int i = 0; i < 32; ++i) { - QString rowName = tr("通道%1").arg(i + 1); - m_model->setHeaderData(i, Qt::Vertical, rowName, Qt::DisplayRole); - } - - // 操作列最后一列不可编辑 - int actionCol = headList.size() - 1; - for (int row = 0; row < 32; ++row) { - QStandardItem *item = new QStandardItem(QString()); - - item->setFlags(item->flags() & ~Qt::ItemIsEditable); - m_model->setItem(row, actionCol, item); - } - - m_tableView->setModel(m_model); - m_tableView->verticalHeader()->setSectionResizeMode(QHeaderView::Interactive); - m_tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive); - m_tableView->setEditTriggers(QAbstractItemView::DoubleClicked); - // 设置代理 - DeviceParameterProxy *proxy = new DeviceParameterProxy(this); - m_tableView->setItemDelegate(proxy); - - setupActionColumnButtons(); -} - -void DeviceConfigView::setupActionColumnButtons() -{ - int actionCol = m_model->columnCount() - 1; - for (int row = 0; row < m_model->rowCount(); ++row) { - QModelIndex idx_0 = m_model->index(row, 0); - - QModelIndex idx = m_model->index(row, actionCol); - QPushButton *btn = new QPushButton(tr("应用"), m_tableView); - btn->setProperty("row", row); - connect(btn, &QPushButton::clicked, this, &DeviceConfigView::onActionButtonClicked); - m_tableView->setIndexWidget(idx, btn); - } -} - -void DeviceConfigView::onActionButtonClicked() -{ - QPushButton *btn = qobject_cast(sender()); - if (!btn) return; - - int srcRow = btn->property("row").toInt(); - int srcChannel = srcRow + 1; - - QList targetChannels = selectTargetChannels(srcChannel); - if (targetChannels.isEmpty()) return; - - int paramColCount = m_model->columnCount() - 1; - m_model->blockSignals(true); - for (int ch : targetChannels) { - int dstRow = ch - 1; - if (dstRow == srcRow) continue; - for (int col = 0; col < paramColCount; ++col) { - QVariant srcData = m_model->data(m_model->index(srcRow, col)); - m_model->setData(m_model->index(dstRow, col), srcData); - } - } - m_model->blockSignals(false); - - emit m_model->dataChanged(m_model->index(0, 0), m_model->index(m_model->rowCount() - 1, paramColCount - 1)); - QMessageBox::information(this, tr("提示"), - tr("已成功将通道%1的参数应用到 %2 个通道").arg(srcChannel).arg(targetChannels.size())); -} - -QList DeviceConfigView::selectTargetChannels(int currentChannel) const -{ - QDialog dlg(const_cast(this)); - dlg.setWindowTitle(tr("选择目标通道")); - dlg.resize(300, 400); - - QVBoxLayout *layout = new QVBoxLayout(&dlg); - QLabel *label = new QLabel(tr("请选择要应用参数的目标通道(可多选):")); - layout->addWidget(label); - - QListWidget *listWidget = new QListWidget(&dlg); - for (int i = 1; i <= 32; ++i) { - QString itemText = tr("通道 %1").arg(i); - if (i == currentChannel) itemText += tr(" (源通道)"); - QListWidgetItem *item = new QListWidgetItem(itemText, listWidget); - item->setFlags(item->flags() | Qt::ItemIsUserCheckable); - item->setCheckState(Qt::Unchecked); - item->setData(Qt::UserRole, i); - if (i == currentChannel) { - item->setFlags(item->flags() & ~Qt::ItemIsEnabled); - } - } - layout->addWidget(listWidget); - - QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, &dlg); - layout->addWidget(buttonBox); - connect(buttonBox, &QDialogButtonBox::accepted, &dlg, &QDialog::accept); - connect(buttonBox, &QDialogButtonBox::rejected, &dlg, &QDialog::reject); - - QList selected; - if (dlg.exec() == QDialog::Accepted) { - for (int i = 0; i < listWidget->count(); ++i) { - QListWidgetItem *item = listWidget->item(i); - if (item->checkState() == Qt::Checked) { - int ch = item->data(Qt::UserRole).toInt(); - if (ch != currentChannel) selected.append(ch); - } - } - } - return selected; -} - -bool DeviceConfigView::loadJson(const QString &filePath) -{ - QFile file(filePath); - if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { - qWarning() << "无法打开文件:" << file.errorString(); - return false; - } - QByteArray jsonData = file.readAll(); - file.close(); - return parseJsonImpl(jsonData); -} - -bool DeviceConfigView::parseJsonImpl(const QByteArray &data) -{ - QJsonParseError parseError; - QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &parseError); - if (parseError.error != QJsonParseError::NoError) { - qWarning() << "JSON 解析错误:" << parseError.errorString(); - return false; - } - if (!jsonDoc.isObject()) { - qWarning() << "JSON 文档不是对象"; - return false; - } - - QJsonObject rootObj = jsonDoc.object(); - QJsonArray channelsArray = rootObj["channels"].toArray(); - - m_model->blockSignals(true); - - // 清空现有数据 - for (int row = 0; row < m_model->rowCount(); ++row) { - for (int col = 0; col < m_model->columnCount(); ++col) { - m_model->setData(m_model->index(row, col), QVariant()); - } - } - - int count = qMin(channelsArray.size(), m_model->rowCount()); - for (int i = 0; i < count; ++i) { - QJsonValue channelValue = channelsArray[i]; - if (!channelValue.isObject()) continue; - QJsonObject channelObj = channelValue.toObject(); - - for (int col = 0; col < m_model->columnCount(); ++col) { - QString header = m_model->headerData(col, Qt::Horizontal).toString(); - QString jsonKey = m_columnToJsonKey.value(header); - if (jsonKey.isEmpty()) continue; - - QJsonValue value = channelObj[jsonKey]; - if (value.isUndefined()) continue; - - if (value.isString()) - m_model->setData(m_model->index(i, col), value.toString()); - else if (value.isDouble()) - m_model->setData(m_model->index(i, col), value.toDouble()); - else if (value.isBool()) - m_model->setData(m_model->index(i, col), value.toBool()); - } - } - - emit m_model->dataChanged(m_model->index(0, 0), m_model->index(m_model->rowCount() - 1, m_model->columnCount() - 1)); - emit dataChanged(); - - m_tableView->viewport()->update(); - m_tableView->horizontalHeader()->update(); - m_tableView->verticalHeader()->update(); - return true; -} - -bool DeviceConfigView::saveJson(const QString &filePath) -{ - QJsonObject rootObj; - rootObj["command"] = "SET"; - QJsonArray channelsArray; - - for (int row = 0; row < m_model->rowCount(); ++row) { - QJsonObject channelObj; - for (int col = 0; col < m_model->columnCount(); ++col) { - QString header = m_model->headerData(col, Qt::Horizontal).toString(); - QString jsonKey = m_columnToJsonKey.value(header); - if (jsonKey.isEmpty()) continue; - - QVariant value = m_model->index(row, col).data(Qt::EditRole); - if (!value.isValid() || value.isNull()) continue; - channelObj[jsonKey] = QJsonValue::fromVariant(value); - } - channelsArray.append(channelObj); - } - - rootObj["channels"] = channelsArray; - - QFile file(filePath); - if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) { - qWarning() << "无法创建文件:" << file.errorString(); - return false; - } - QJsonDocument doc(rootObj); - file.write(doc.toJson()); - file.close(); - return true; -} - -QStandardItemModel* DeviceConfigView::getModel() const -{ - return m_model; -} - -void DeviceConfigView::showColumnControlDialog() -{ - int colCount = m_model->columnCount(); - if (colCount == 0) return; - - QDialog dlg(this); - dlg.setWindowTitle(tr("列显示控制")); - dlg.resize(800, 400); - dlg.setWindowModality(Qt::WindowModal); - - QVBoxLayout *mainLayout = new QVBoxLayout(&dlg); - - // 工具栏 - QHBoxLayout *row1Layout = new QHBoxLayout(); - QPushButton *btnSelectAll = new QPushButton(tr("全选")); - QPushButton *btnInvert = new QPushButton(tr("反选")); - QPushButton *btnSave = new QPushButton(tr("保存配置")); - QPushButton *btnLoad = new QPushButton(tr("加载配置")); - row1Layout->addWidget(btnSelectAll); - row1Layout->addWidget(btnInvert); - row1Layout->addWidget(btnSave); - row1Layout->addWidget(btnLoad); - row1Layout->addStretch(); - mainLayout->addLayout(row1Layout); - - QScrollArea *scrollArea = new QScrollArea(); - scrollArea->setWidgetResizable(true); - QWidget *scrollWidget = new QWidget(); - QGridLayout *gridLayout = new QGridLayout(scrollWidget); - scrollArea->setWidget(scrollWidget); - mainLayout->addWidget(scrollArea); - - int gridCols = std::sqrt(colCount); - if (gridCols < 1) gridCols = 1; - - QMap colCheckBoxMap; - for (int col = 0; col < colCount; ++col) { - QString header = m_model->headerData(col, Qt::Horizontal).toString(); - QCheckBox *cb = new QCheckBox(header); - cb->setChecked(!m_tableView->isColumnHidden(col)); - connect(cb, &QCheckBox::toggled, this, [this, col](bool checked) { - m_tableView->setColumnHidden(col, !checked); - }); - int row = col / gridCols; - int colInGrid = col % gridCols; - gridLayout->addWidget(cb, row, colInGrid); - colCheckBoxMap[col] = cb; - } - - connect(btnSelectAll, &QPushButton::clicked, this, [colCheckBoxMap, this]() { - // 先断开所有复选框的信号 - for (QCheckBox *cb : colCheckBoxMap) { - cb->blockSignals(true); - cb->setChecked(true); - cb->blockSignals(false); - } - // 一次性更新所有列的隐藏状态 - for (int col : colCheckBoxMap.keys()) { - m_tableView->setColumnHidden(col, !colCheckBoxMap[col]->isChecked()); - } - }); - connect(btnInvert, &QPushButton::clicked, this, [colCheckBoxMap, this]() { - for (QCheckBox *cb : colCheckBoxMap) { - cb->blockSignals(true); - cb->setChecked(!cb->isChecked()); - cb->blockSignals(false); - } - for (int col : colCheckBoxMap.keys()) { - m_tableView->setColumnHidden(col, !colCheckBoxMap[col]->isChecked()); - } - }); - connect(btnSave, &QPushButton::clicked, this, [this, &dlg, colCheckBoxMap]() { - QString saveDir = QDir::currentPath() + "/columnConfigs"; - QDir().mkpath(saveDir); - QString fileName = QFileDialog::getSaveFileName(&dlg, tr("保存列配置"), - saveDir + "/untitled.json", - "JSON Files (*.json)"); - if (fileName.isEmpty()) return; - - QJsonObject root; - for (int col = 0; col < m_model->columnCount(); ++col) { - QString header = m_model->headerData(col, Qt::Horizontal).toString(); - bool checked = colCheckBoxMap[col]->isChecked(); - root[header] = checked; - } - - QJsonDocument doc(root); - QFile file(fileName); - if (file.open(QIODevice::WriteOnly)) { - file.write(doc.toJson()); - file.close(); - QMessageBox::information(&dlg, tr("成功"), tr("列配置已保存")); - } else { - QMessageBox::warning(&dlg, tr("错误"), tr("无法保存文件:%1").arg(file.errorString())); - } - }); - - connect(btnLoad, &QPushButton::clicked, this, [this, &dlg, colCheckBoxMap]() { - QString loadDir = QDir::currentPath() + "/columnConfigs"; - QString fileName = QFileDialog::getOpenFileName(&dlg, tr("加载列配置"), - loadDir, "JSON Files (*.json)"); - if (fileName.isEmpty()) return; - - QFile file(fileName); - if (!file.open(QIODevice::ReadOnly)) { - QMessageBox::warning(&dlg, tr("错误"), tr("无法打开文件:%1").arg(file.errorString())); - return; - } - QByteArray data = file.readAll(); - file.close(); - - QJsonParseError err; - QJsonDocument doc = QJsonDocument::fromJson(data, &err); - if (err.error != QJsonParseError::NoError || !doc.isObject()) { - QMessageBox::warning(&dlg, tr("错误"), tr("JSON解析失败")); - return; - } - - QJsonObject root = doc.object(); - for (int col = 0; col < m_model->columnCount(); ++col) { - QString header = m_model->headerData(col, Qt::Horizontal).toString(); - if (root.contains(header)) { - colCheckBoxMap[col]->blockSignals(true); - colCheckBoxMap[col]->setChecked(root[header].toBool(false)); - colCheckBoxMap[col]->blockSignals(false); - } - } - // 一次性更新列隐藏 - for (int col : colCheckBoxMap.keys()) { - m_tableView->setColumnHidden(col, !colCheckBoxMap[col]->isChecked()); - } - }); - - dlg.exec(); -} - -void DeviceConfigView::reset() -{ - m_model->blockSignals(true); - for (int row = 0; row < m_model->rowCount(); ++row) { - for (int col = 0; col < m_model->columnCount(); ++col) { - m_model->setData(m_model->index(row, col), QVariant()); - } - } - m_model->blockSignals(false); - emit m_model->dataChanged(m_model->index(0, 0), m_model->index(m_model->rowCount() - 1, m_model->columnCount() - 1)); -} - -void DeviceConfigView::setColumnMapping(const QHash &mapping) -{ - m_columnToJsonKey = mapping; - // 构建反向映射(可选) - m_jsonKeyToColumn.clear(); - for (auto it = m_columnToJsonKey.constBegin(); it != m_columnToJsonKey.constEnd(); ++it) { - m_jsonKeyToColumn[it.value()] = m_model->headerData(0, Qt::Horizontal, Qt::DisplayRole).toString().indexOf(it.key()); - } -} - -void DeviceConfigView::InitViewWorkspace(const QString &project_name) -{ - -} - -void DeviceConfigView::SetAnalyzeDataFilename(const QMap &data_files_set) -{ - if (data_files_set.isEmpty()) { - LOG_WARN("文件集合为空"); - return; - } - - QString filePath = data_files_set.first().toString(); - LOG_INFO("读取文件: " + filePath); -} diff --git a/src/DeviceParameterConfig/DeviceConfigView.h b/src/DeviceParameterConfig/DeviceConfigView.h deleted file mode 100644 index 8f6e95c..0000000 --- a/src/DeviceParameterConfig/DeviceConfigView.h +++ /dev/null @@ -1,62 +0,0 @@ -#ifndef DEVICECONFIGVIEW_H -#define DEVICECONFIGVIEW_H - -#include -#include -#include "MeasureAnalysisView.h" - -class QTableView; -class QStandardItemModel; -class QPushButton; - - -class DeviceConfigView : public MeasureAnalysisView -{ - Q_OBJECT -public: - explicit DeviceConfigView(QWidget *parent = nullptr); - ~DeviceConfigView(); - - - bool loadJson(const QString &filePath); - - - bool saveJson(const QString &filePath); - - - QStandardItemModel* getModel() const; - - - void showColumnControlDialog(); - - - void reset(); - - - void setColumnMapping(const QHash &mapping); - - virtual void InitViewWorkspace(const QString& project_name) override final; - virtual void SetAnalyzeDataFilename(const QMap& data_files_set); - - QList getCheckedRows() const; - -signals: - - void dataChanged(); - -private slots: - void onActionButtonClicked(); - -private: - void initTableView(); - void setupActionColumnButtons(); - bool parseJsonImpl(const QByteArray &data); - QList selectTargetChannels(int currentChannel) const; - - QTableView *m_tableView; - QStandardItemModel *m_model; - QHash m_columnToJsonKey; // 列头 -> JSON键名 - QHash m_jsonKeyToColumn; // 反向映射,用于快速查找列索引 -}; - -#endif // DEVICECONFIGVIEW_H diff --git a/src/DeviceParameterConfig/DeviceParameterConfig.cpp b/src/DeviceParameterConfig/DeviceParameterConfig.cpp deleted file mode 100644 index 53ca720..0000000 --- a/src/DeviceParameterConfig/DeviceParameterConfig.cpp +++ /dev/null @@ -1,333 +0,0 @@ -#include "DeviceParameterConfig.h" -#include "DeviceParameterConfigList.h" -#include "DeviceConfigView.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -DeviceParameterConfig::DeviceParameterConfig(QWidget *parent) - : QWidget(parent) - , m_configList(nullptr) - , m_configView(nullptr) - , m_lineEditFileName(nullptr) - , m_textEditRemark(nullptr) - , m_checkBoxSaveToDevice(nullptr) - , m_btnSave(nullptr) - , m_btnSetColumn(nullptr) -{ - setupUi(); - initColumnMapping(); // 设置默认映射 - m_configView->setColumnMapping(m_columnToJsonKey); - m_configList->loadConfigsFromFolder(); // 加载默认目录下的配置文件 -} - -DeviceParameterConfig::~DeviceParameterConfig() -{ -} - -void DeviceParameterConfig::setupUi() -{ - // 主布局:左右分栏 - QHBoxLayout *mainLayout = new QHBoxLayout(this); - mainLayout->setContentsMargins(0, 0, 0, 0); - mainLayout->setSpacing(10); - - // 左侧:配置列表 - m_configList = new DeviceParameterConfigList(this); - mainLayout->addWidget(m_configList, 1); - - // 右侧:垂直布局 - QVBoxLayout *rightLayout = new QVBoxLayout(); - mainLayout->addLayout(rightLayout, 9); - - // 右侧上部:文件名、保存按钮、备注说明 - QHBoxLayout *topLayout = new QHBoxLayout(); - QLabel *labelName = new QLabel(QStringLiteral(u"配置命名:"), this); - m_lineEditFileName = new QLineEdit(this); - m_btnSave = new QPushButton(QStringLiteral(u"保存到测量分析"), this); - m_checkBoxSaveToDevice = new QCheckBox(QStringLiteral(u"保存到设备参数配置管理"), this); - topLayout->addWidget(labelName); - topLayout->addWidget(m_lineEditFileName, 1); - topLayout->addWidget(m_btnSave); - topLayout->addWidget(m_checkBoxSaveToDevice); - rightLayout->addLayout(topLayout); - - QHBoxLayout *remarkLayout = new QHBoxLayout(); - QLabel *labelRemark = new QLabel(QStringLiteral(u"备注说明:"), this); - m_textEditRemark = new QTextEdit(this); - m_textEditRemark->setMaximumHeight(80); - remarkLayout->addWidget(labelRemark); - remarkLayout->addWidget(m_textEditRemark, 1); - rightLayout->addLayout(remarkLayout); - - // 右侧中部:设置列按钮 - QHBoxLayout *buttonLayout = new QHBoxLayout(); - m_btnSetColumn = new QPushButton(QStringLiteral(u"设置列"), this); - buttonLayout->addWidget(m_btnSetColumn); - buttonLayout->addStretch(); - rightLayout->addLayout(buttonLayout); - - // 右侧下部:参数表格视图 - m_configView = new DeviceConfigView(this); - rightLayout->addWidget(m_configView, 1); - - // 连接信号槽 - connect(m_configList, &DeviceParameterConfigList::configSelected, - this, &DeviceParameterConfig::onConfigSelected); - connect(m_configList, &DeviceParameterConfigList::configDeleted, - this, &DeviceParameterConfig::onConfigDeleted); - connect(m_btnSave, &QPushButton::clicked, - this, &DeviceParameterConfig::onSaveButtonClicked); - connect(m_btnSetColumn, &QPushButton::clicked, - this, &DeviceParameterConfig::onSetColumnButtonClicked); - connect(m_configList, &DeviceParameterConfigList::createNewConfigRequested, - this, &DeviceParameterConfig::onCreateNewConfigRequested); - connect(m_configView, &DeviceConfigView::dataChanged, - this, [this]() { - // 数据改变时,在文件名后添加星号表示未保存 - if (!m_lineEditFileName->text().isEmpty() && !m_lineEditFileName->text().endsWith(" *")) { - m_lineEditFileName->setText(m_lineEditFileName->text() + " *"); - } - }); -} - -void DeviceParameterConfig::initColumnMapping() -{ - // 与原 EquipmentParameterSettingManagement 完全相同的映射 - m_columnToJsonKey.clear(); - m_columnToJsonKey[QStringLiteral(u"数据传输模式")] = "eTransferModel"; - m_columnToJsonKey[QStringLiteral(u"硬件增益")] = "iDeviceGain"; - m_columnToJsonKey[QStringLiteral(u"硬件增益选择索引")] = "iDeviceGainSelectIndex"; - m_columnToJsonKey[QStringLiteral(u"软件增益")] = "iSoftGain"; - m_columnToJsonKey[QStringLiteral(u"时间常数")] = "dConstTime"; - m_columnToJsonKey[QStringLiteral(u"成形时间")] = "iFormTime"; - m_columnToJsonKey[QStringLiteral(u"快通道触发阈值")] = "iFastChannelTrigerValue"; - m_columnToJsonKey[QStringLiteral(u"多道分辨率")] = "iChannelNum"; - m_columnToJsonKey[QStringLiteral(u"控制功能")] = ""; - m_columnToJsonKey[QStringLiteral(u"幅度提前延迟")] = ""; - m_columnToJsonKey[QStringLiteral(u"积分长度")] = ""; - m_columnToJsonKey[QStringLiteral(u"dcfd缩放倍数")] = ""; - m_columnToJsonKey[QStringLiteral(u"dcfd延迟")] = ""; - m_columnToJsonKey[QStringLiteral(u"直流偏移")] = "iCurrentOffset"; - m_columnToJsonKey[QStringLiteral(u"最大能量范围")] = "iMaxEnergy"; - m_columnToJsonKey[QStringLiteral(u"Am 峰面积寻峰法的面积比例")] = "iAMPeakDiv"; - m_columnToJsonKey[QStringLiteral(u"K40与 Am241的峰位校正系数")] = "iHVDelt"; - m_columnToJsonKey[QStringLiteral(u"高压关断阈值")] = "iHVDelt"; - m_columnToJsonKey[QStringLiteral(u"获取能谱周期")] = "iGetSpecturmPeirod"; - m_columnToJsonKey[QStringLiteral(u"总测量时间")] = "iTotalMeasureTime"; - m_columnToJsonKey[QStringLiteral(u"总测量次数")] = "iTotalMeasureCount"; - m_columnToJsonKey[QStringLiteral(u"滤波参数")] = "iTrapeTopShitBit"; - m_columnToJsonKey[QStringLiteral(u"上升时间")] = "iRiseTime"; - m_columnToJsonKey[QStringLiteral(u"平顶时间")] = "iTopTime"; - m_columnToJsonKey[QStringLiteral(u"ICR 校正使能")] = "bICRCorrect"; - m_columnToJsonKey[QStringLiteral(u"CRZA 值")] = "iCRZAValue"; - m_columnToJsonKey[QStringLiteral(u"ZA 使能值")] = "iZAEnable"; -} - -void DeviceParameterConfig::setColumnMapping(const QHash &mapping) -{ - m_columnToJsonKey = mapping; - m_configView->setColumnMapping(mapping); -} - -bool DeviceParameterConfig::loadConfig(const QString &filePath) -{ - if (!m_configView->loadJson(filePath)) - return false; - - m_currentFilePath = filePath; - QFileInfo info(filePath); - m_lineEditFileName->setText(info.fileName()); - - // 读取 JSON 中的备注字段 - QFile file(filePath); - if (file.open(QIODevice::ReadOnly)) { - QByteArray data = file.readAll(); - file.close(); - QJsonDocument doc = QJsonDocument::fromJson(data); - if (doc.isObject()) { - QJsonObject obj = doc.object(); - if (obj.contains("remark")) { - m_textEditRemark->setPlainText(obj["remark"].toString()); - } else { - m_textEditRemark->clear(); - } - } - } - - emit configLoaded(filePath); // 此信号未在头文件中声明,可添加;若不需要可移除 - return true; -} - -bool DeviceParameterConfig::saveCurrentConfig() -{ - if (m_currentFilePath.isEmpty()) { - QMessageBox::warning(this, QStringLiteral(u"错误"), QStringLiteral(u"没有选中的配置文件")); - return false; - } - - // 保存表格数据 - if (!m_configView->saveJson(m_currentFilePath)) - return false; - - // 保存备注到 JSON - QFile file(m_currentFilePath); - if (!file.open(QIODevice::ReadOnly)) { - qWarning() << "无法打开文件读取备注:" << file.errorString(); - return false; - } - QByteArray data = file.readAll(); - file.close(); - - QJsonDocument doc = QJsonDocument::fromJson(data); - if (!doc.isObject()) { - qWarning() << "JSON 不是对象"; - return false; - } - QJsonObject root = doc.object(); - root["remark"] = m_textEditRemark->toPlainText(); - - if (!file.open(QIODevice::WriteOnly)) { - qWarning() << "无法写入文件:" << file.errorString(); - return false; - } - file.write(QJsonDocument(root).toJson()); - file.close(); - - // 移除文件名后的星号 - QString fileName = m_lineEditFileName->text(); - if (fileName.endsWith(" *")) - fileName.chop(2); - m_lineEditFileName->setText(fileName); - - return true; -} - -QString DeviceParameterConfig::getCurrentFileName() const -{ - return QFileInfo(m_currentFilePath).fileName(); -} - -QString DeviceParameterConfig::getRemark() const -{ - return m_textEditRemark->toPlainText(); -} - -void DeviceParameterConfig::setRemark(const QString &remark) -{ - m_textEditRemark->setPlainText(remark); -} - -void DeviceParameterConfig::onConfigSelected(const QString &filePath) -{ - loadConfig(filePath); -} - -void DeviceParameterConfig::onConfigDeleted(const QString &fileName) -{ - if (m_lineEditFileName->text() == fileName) { - m_lineEditFileName->clear(); - m_textEditRemark->clear(); - m_configView->reset(); - m_currentFilePath.clear(); - } -} - -void DeviceParameterConfig::onCreateNewConfigRequested(const QString &fileName) -{ - QString filePath = QDir::currentPath() + "/parameterConfig/" + fileName; - if (createDefaultConfigFile(filePath)) { - // 刷新列表 - m_configList->refresh(); - // 选中新建的文件 - m_configList->setCurrentFile(fileName); - // 自动加载该配置(可选) - loadConfig(filePath); - } else { - QMessageBox::warning(this, QStringLiteral(u"错误"), QStringLiteral(u"无法创建配置文件:%1").arg(filePath)); - } -} - -void DeviceParameterConfig::onSaveButtonClicked() -{ - if (!saveCurrentConfig()) { - QMessageBox::warning(this, QStringLiteral(u"错误"), QStringLiteral(u"保存配置文件失败")); - return; - } - - // 如果勾选了“保存到设备参数配置管理”,刷新左侧列表 - if (m_checkBoxSaveToDevice->isChecked()) { - m_configList->refresh(); - } - - // 发出信号,供外部处理(例如将参数发送到测量分析模块) - emit saveToMeasurementRequested(m_currentFilePath); -} - -void DeviceParameterConfig::onSetColumnButtonClicked() -{ - m_configView->showColumnControlDialog(); -} - -bool DeviceParameterConfig::createDefaultConfigFile(const QString &filePath) -{ - // 创建默认配置文件(含 32 个通道) - QJsonObject rootObj; - rootObj["command"] = "SET"; - QJsonArray channelsArray; - - QJsonObject defaultChannel; - defaultChannel["eTransferModel"] = "eSpecturmMode"; - defaultChannel["iDeviceGain"] = 1; - defaultChannel["iDeviceGainSelectIndex"] = 1; - defaultChannel["iSoftGain"] = 3000; - defaultChannel["dConstTime"] = 45.0; - defaultChannel["iFormTime"] = 3; - defaultChannel["iFastChannelTrigerValue"] = 10.0; - defaultChannel["iChannelNum"] = 1024; - defaultChannel["iHighVoltage"] = 0; - defaultChannel["iInputVoltageDesc"] = 0; - defaultChannel["iCRDivMode"] = 0; - defaultChannel["iInputSignalPostive"] = 0; - defaultChannel["iCurrentOffset"] = 0; - defaultChannel["iMaxEnergy"] = 0; - defaultChannel["iAMPeakDiv"] = 0; - defaultChannel["iHVDelt"] = 0; - defaultChannel["iHVCtrl"] = 0; - defaultChannel["iGetSpecturmPeirod"] = 1; - defaultChannel["iTotalMeasureTime"] = 10; - defaultChannel["iTotalMeasureCount"] = 1; - defaultChannel["iTrapeTopShitBit"] = 0; - defaultChannel["iRiseTime"] = 2; - defaultChannel["iTopTime"] = 2; - defaultChannel["bICRCorrect"] = false; - defaultChannel["iCRZAValue"] = 0; - defaultChannel["iZAEnable"] = 30; - defaultChannel["reserve"] = QJsonArray(); - defaultChannel["pUserConfigInfo"] = QJsonObject(); - - for (int i = 0; i < 32; ++i) { - channelsArray.append(defaultChannel); - } - rootObj["channels"] = channelsArray; - rootObj["remark"] = ""; - - QJsonDocument doc(rootObj); - QFile file(filePath); - if (!file.open(QIODevice::WriteOnly)) - return false; - file.write(doc.toJson()); - file.close(); - return true; -} diff --git a/src/DeviceParameterConfig/DeviceParameterConfig.h b/src/DeviceParameterConfig/DeviceParameterConfig.h deleted file mode 100644 index 07dbebb..0000000 --- a/src/DeviceParameterConfig/DeviceParameterConfig.h +++ /dev/null @@ -1,73 +0,0 @@ -#ifndef DEVICEPARAMETERCONFIG_H -#define DEVICEPARAMETERCONFIG_H - -#include -#include - -class DeviceParameterConfigList; -class DeviceConfigView; -class QLineEdit; -class QTextEdit; -class QCheckBox; -class QPushButton; - - -class DeviceParameterConfig : public QWidget -{ - Q_OBJECT -public: - explicit DeviceParameterConfig(QWidget *parent = nullptr); - ~DeviceParameterConfig(); - - - void setColumnMapping(const QHash &mapping); - - - bool loadConfig(const QString &filePath); - - - bool saveCurrentConfig(); - - - QString getCurrentFileName() const; - - - QString getRemark() const; - - - void setRemark(const QString &remark); - -signals: - - void saveToMeasurementRequested(const QString &filePath); - - void configLoaded(QString ); - -private slots: - void onConfigSelected(const QString &filePath); - void onConfigDeleted(const QString &fileName); - void onCreateNewConfigRequested(const QString &fileName); - void onSaveButtonClicked(); - void onSetColumnButtonClicked(); - -private: - void setupUi(); - bool createDefaultConfigFile(const QString &filePath); - void initColumnMapping(); // 初始化默认映射(若外部未调用则使用默认) - - // 子控件 - DeviceParameterConfigList *m_configList; - DeviceConfigView *m_configView; - - // 周边控件 - QLineEdit *m_lineEditFileName; - QTextEdit *m_textEditRemark; - QCheckBox *m_checkBoxSaveToDevice; - QPushButton *m_btnSave; - QPushButton *m_btnSetColumn; - - QString m_currentFilePath; - QHash m_columnToJsonKey; // 列头->JSON键映射 -}; - -#endif // DEVICEPARAMETERCONFIG_H diff --git a/src/DeviceParameterConfig/DeviceParameterConfigList.cpp b/src/DeviceParameterConfig/DeviceParameterConfigList.cpp deleted file mode 100644 index 5c64baf..0000000 --- a/src/DeviceParameterConfig/DeviceParameterConfigList.cpp +++ /dev/null @@ -1,214 +0,0 @@ -#include "DeviceParameterConfigList.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -DeviceParameterConfigList::DeviceParameterConfigList(QWidget *parent) - : QWidget(parent) - , m_listWidget(nullptr) - , m_btnAdd(nullptr) - , m_btnDelete(nullptr) -{ - setupUi(); -} - -DeviceParameterConfigList::~DeviceParameterConfigList() -{ -} - -void DeviceParameterConfigList::setupUi() -{ - QVBoxLayout *mainLayout = new QVBoxLayout(this); - mainLayout->setContentsMargins(0, 0, 0, 0); - - QLabel *ListWidgetName = new QLabel(QStringLiteral(u"设备参数配置列表")); - mainLayout->addWidget(ListWidgetName); - - m_listWidget = new QListWidget(this); - mainLayout->addWidget(m_listWidget); - - QHBoxLayout *btnLayout = new QHBoxLayout(); - m_btnAdd = new QPushButton(QStringLiteral(u"添加"), this); - m_btnDelete = new QPushButton(QStringLiteral(u"删除"), this); - btnLayout->addWidget(m_btnAdd); - btnLayout->addWidget(m_btnDelete); - btnLayout->addStretch(); - mainLayout->addLayout(btnLayout); - - connect(m_listWidget, &QListWidget::itemClicked, this, &DeviceParameterConfigList::onItemClicked); - connect(m_btnAdd, &QPushButton::clicked, this, &DeviceParameterConfigList::onAddClicked); - connect(m_btnDelete, &QPushButton::clicked, this, &DeviceParameterConfigList::onDeleteClicked); -} - -void DeviceParameterConfigList::loadConfigsFromFolder(const QString &folderPath) -{ - if (folderPath.isEmpty()) { - m_folderPath = QDir::currentPath() + "/parameterConfig"; - } else { - m_folderPath = folderPath; - } - - QDir dir(m_folderPath); - if (!dir.exists()) { - dir.mkpath(m_folderPath); - } - - dir.setFilter(QDir::Files | QDir::NoDotAndDotDot); - QStringList files = dir.entryList(); - updateList(files); -} - -void DeviceParameterConfigList::updateList(const QStringList &fileList) -{ - m_listWidget->clear(); - for (const QString &file : fileList) { - if (file.endsWith(".json", Qt::CaseInsensitive)) { - m_listWidget->addItem(file); - } - } -} - -QString DeviceParameterConfigList::getCurrentFilePath() const -{ - QListWidgetItem *item = m_listWidget->currentItem(); - if (!item) return QString(); - return m_folderPath + "/" + item->text(); -} - -QString DeviceParameterConfigList::getCurrentFileName() const -{ - QListWidgetItem *item = m_listWidget->currentItem(); - return item ? item->text() : QString(); -} - -void DeviceParameterConfigList::setCurrentFile(const QString &fileName) -{ - QList items = m_listWidget->findItems(fileName, Qt::MatchExactly); - if (!items.isEmpty()) { - m_listWidget->setCurrentItem(items.first()); - emit configSelected(getCurrentFilePath()); - } -} - -void DeviceParameterConfigList::refresh() -{ - loadConfigsFromFolder(m_folderPath); -} - -void DeviceParameterConfigList::onItemClicked(QListWidgetItem *item) -{ - if (item) { - emit configSelected(m_folderPath + "/" + item->text()); - } -} - -void DeviceParameterConfigList::onAddClicked() -{ - bool ok; - QString fileName = QInputDialog::getText(this, QStringLiteral(u"新建配置"), - QStringLiteral(u"请输入配置文件名(无需后缀):"), - QLineEdit::Normal, - QString("NewConfig_%1").arg(QDateTime::currentDateTime().toString("yyyyMMdd_hhmmss")), - &ok); - if (!ok || fileName.isEmpty()) return; - - if (!fileName.endsWith(".json", Qt::CaseInsensitive)) - fileName += ".json"; - - QString filePath = m_folderPath + "/" + fileName; - if (QFile::exists(filePath)) { - QMessageBox::warning(this, QStringLiteral(u"错误"), QStringLiteral(u"文件已存在,请使用其他名称。")); - return; - } - - // 发出创建请求,由外部(主窗口)决定默认内容 - emit createNewConfigRequested(fileName); -} - -void DeviceParameterConfigList::onDeleteClicked() -{ - QListWidgetItem *currentItem = m_listWidget->currentItem(); - if (!currentItem) { - QMessageBox::information(this, QStringLiteral(u"提示"), QStringLiteral(u"请先选择要删除的配置文件。")); - return; - } - - QString fileName = currentItem->text(); - QString filePath = m_folderPath + "/" + fileName; - - int ret = QMessageBox::question(this, QStringLiteral(u"确认删除"), - QStringLiteral(u"确定要删除文件 \"%1\" 吗?").arg(fileName), - QMessageBox::Yes | QMessageBox::No); - if (ret != QMessageBox::Yes) return; - - QFile file(filePath); - if (file.remove()) { - delete currentItem; - emit configDeleted(fileName); - QMessageBox::information(this, QStringLiteral(u"成功"), QStringLiteral(u"文件已删除。")); - } else { - QMessageBox::warning(this, QStringLiteral(u"错误"), QStringLiteral(u"无法删除文件:%1").arg(file.errorString())); - } -} - -bool DeviceParameterConfigList::createDefaultConfigFile(const QString &filePath) -{ - // 默认配置内容(与原来保持一致) - QJsonObject rootObj; - rootObj["command"] = "SET"; - QJsonArray channelsArray; - - QJsonObject defaultChannel; - defaultChannel["eTransferModel"] = "eSpecturmMode"; - defaultChannel["iDeviceGain"] = 1; - defaultChannel["iDeviceGainSelectIndex"] = 1; - defaultChannel["iSoftGain"] = 3000; - defaultChannel["dConstTime"] = 45.0; - defaultChannel["iFormTime"] = 3; - defaultChannel["iFastChannelTrigerValue"] = 10.0; - defaultChannel["iChannelNum"] = 1024; - defaultChannel["iHighVoltage"] = 0; - defaultChannel["iInputVoltageDesc"] = 0; - defaultChannel["iCRDivMode"] = 0; - defaultChannel["iInputSignalPostive"] = 0; - defaultChannel["iCurrentOffset"] = 0; - defaultChannel["iMaxEnergy"] = 0; - defaultChannel["iAMPeakDiv"] = 0; - defaultChannel["iHVDelt"] = 0; - defaultChannel["iHVCtrl"] = 0; - defaultChannel["iGetSpecturmPeirod"] = 1; - defaultChannel["iTotalMeasureTime"] = 10; - defaultChannel["iTotalMeasureCount"] = 1; - defaultChannel["iTrapeTopShitBit"] = 0; - defaultChannel["iRiseTime"] = 2; - defaultChannel["iTopTime"] = 2; - defaultChannel["bICRCorrect"] = false; - defaultChannel["iCRZAValue"] = 0; - defaultChannel["iZAEnable"] = 30; - defaultChannel["reserve"] = QJsonArray(); - defaultChannel["pUserConfigInfo"] = QJsonObject(); - - for (int i = 0; i < 32; ++i) { - channelsArray.append(defaultChannel); - } - rootObj["channels"] = channelsArray; - - QJsonDocument doc(rootObj); - QFile file(filePath); - if (!file.open(QIODevice::WriteOnly)) { - return false; - } - file.write(doc.toJson()); - file.close(); - return true; -} diff --git a/src/DeviceParameterConfig/DeviceParameterConfigList.h b/src/DeviceParameterConfig/DeviceParameterConfigList.h deleted file mode 100644 index d4707b1..0000000 --- a/src/DeviceParameterConfig/DeviceParameterConfigList.h +++ /dev/null @@ -1,56 +0,0 @@ -#ifndef DEVICEPARAMETERCONFIGLIST_H -#define DEVICEPARAMETERCONFIGLIST_H - -#include -#include - -class QListWidget; -class QPushButton; - - -class DeviceParameterConfigList : public QWidget -{ - Q_OBJECT -public: - explicit DeviceParameterConfigList(QWidget *parent = nullptr); - ~DeviceParameterConfigList(); - - - void loadConfigsFromFolder(const QString &folderPath = QString()); - - - QString getCurrentFilePath() const; - - - QString getCurrentFileName() const; - - - void setCurrentFile(const QString &fileName); - - void refresh(); - -signals: - - void configSelected(const QString &filePath); - - void configDeleted(const QString &fileName); - - void createNewConfigRequested(const QString &fileName); - -private slots: - void onItemClicked(QListWidgetItem *item); - void onAddClicked(); - void onDeleteClicked(); - -private: - void setupUi(); - void updateList(const QStringList &fileList); - bool createDefaultConfigFile(const QString &filePath); - - QListWidget *m_listWidget; - QPushButton *m_btnAdd; - QPushButton *m_btnDelete; - QString m_folderPath; -}; - -#endif // DEVICEPARAMETERCONFIGLIST_H diff --git a/src/DeviceParameterConfig/DeviceParameterProxy.cpp b/src/DeviceParameterConfig/DeviceParameterProxy.cpp deleted file mode 100644 index fb478de..0000000 --- a/src/DeviceParameterConfig/DeviceParameterProxy.cpp +++ /dev/null @@ -1,384 +0,0 @@ -#include "DeviceParameterProxy.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -DeviceParameterProxy::DeviceParameterProxy(QObject *parent) : QStyledItemDelegate(parent) -{ -} - -QWidget* DeviceParameterProxy::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const -{ - int col = index.column(); - switch (col) - { - case 0: // 数据传输模式(枚举) - { - QComboBox *combo = new QComboBox(parent); - combo->addItems(QStringList() << QStringLiteral(u"谱线模式") << QStringLiteral(u"波形模式") << QStringLiteral(u"ADC模式") << QStringLiteral(u"列表模式") << QStringLiteral(u"α/β模式")); - return combo; - } - case 1: // 硬件增益(档位) - { - QComboBox *combo = new QComboBox(parent); - combo->addItems(QStringList() << QStringLiteral(u"1") << QStringLiteral(u"2") << QStringLiteral(u"4") << QStringLiteral(u"8") << QStringLiteral(u"16")); - return combo; - } - case 2: // 硬件增益选择索引 - { - QComboBox *combo = new QComboBox(parent); - combo->addItems(QStringList() << QStringLiteral(u"1") << QStringLiteral(u"2") << QStringLiteral(u"3") << QStringLiteral(u"4") << QStringLiteral(u"5")); - return combo; - } - case 3: // 软件增益(32位无符号) - { - QLineEdit *edit = new QLineEdit(parent); - edit->setValidator(new UInt32Validator(edit)); - edit->setProperty("rangeHint", "0 ~ 4294967295"); - edit->installEventFilter(const_cast(this)); - return edit; - } - case 4: // 时间常数(double μs) - { - QDoubleSpinBox *spin = new QDoubleSpinBox(parent); - spin->setRange(0.0, 1000.0); - spin->setSingleStep(1.0); - spin->setDecimals(2); - return spin; - } - case 5: // 成形时间(int μs) - { - QSpinBox *spin = new QSpinBox(parent); - spin->setRange(1, 10); - return spin; - } - case 6: // 快通道触发阈值(double 0.1mV) - { - QDoubleSpinBox *spin = new QDoubleSpinBox(parent); - spin->setRange(0.0, 10000.0); - spin->setSingleStep(0.1); - spin->setDecimals(1); - return spin; - } - case 7: // 多道分辨率(2的幂) - { - QComboBox *combo = new QComboBox(parent); - combo->addItems(QStringList() << QStringLiteral(u"256") << QStringLiteral(u"512") << QStringLiteral(u"1024") << QStringLiteral(u"2048") << QStringLiteral(u"4096") << QStringLiteral(u"8192") << QStringLiteral(u"16384")); - return combo; - } - case 8: // 控制功能(位掩码,暂用十进制输入) - { - QLineEdit *edit = new QLineEdit(parent); - // 允许输入十进制数字,不设范围限制(业务层处理) - return edit; - } - case 9: // 幅度提前延迟(unsigned char) - { - QSpinBox *spin = new QSpinBox(parent); - spin->setRange(0, 255); - return spin; - } - case 10: // 积分长度(unsigned char) - { - QSpinBox *spin = new QSpinBox(parent); - spin->setRange(0, 255); - return spin; - } - case 11: // dcfd缩放倍数(unsigned char) - { - QSpinBox *spin = new QSpinBox(parent); - spin->setRange(0, 255); - return spin; - } - case 12: // dcfd延迟(unsigned char) - { - QSpinBox *spin = new QSpinBox(parent); - spin->setRange(0, 255); - return spin; - } - case 13: // 直流偏移(mV) - { - QSpinBox *spin = new QSpinBox(parent); - spin->setRange(-1000, 1000); - return spin; - } - case 14: // 最大能量范围(keV) - { - QSpinBox *spin = new QSpinBox(parent); - spin->setRange(0, 99999); - return spin; - } - case 15: // Am峰面积寻峰法的面积比例(%) - { - QSpinBox *spin = new QSpinBox(parent); - spin->setRange(0, 100); - return spin; - } - case 16: // K40与Am241的峰位校正系数(short) - { - QSpinBox *spin = new QSpinBox(parent); - spin->setRange(-32768, 32767); - return spin; - } - case 17: // 高压关断阈值(short) - { - QSpinBox *spin = new QSpinBox(parent); - spin->setRange(-32768, 32767); - return spin; - } - case 18: // 获取能谱周期(秒) - { - QSpinBox *spin = new QSpinBox(parent); - spin->setRange(0, 86400); // 一天 - return spin; - } - case 19: // 总测量时间(__int64,64位) - { - QLineEdit *edit = new QLineEdit(parent); - edit->setValidator(new Int64Validator(edit)); - edit->setProperty("rangeHint", "0 ~ 9223372036854775807"); - edit->installEventFilter(const_cast(this)); - return edit; - } - case 20: // 总测量次数 - { - QSpinBox *spin = new QSpinBox(parent); - spin->setRange(0, 1000000); // 可调大 - return spin; - } - case 21: // 滤波参数 - { - QSpinBox *spin = new QSpinBox(parent); - spin->setRange(0, 3); - return spin; - } - case 22: // 上升时间(μs) - { - QSpinBox *spin = new QSpinBox(parent); - spin->setRange(1, 255); - return spin; - } - case 23: // 平顶时间(μs) - { - QSpinBox *spin = new QSpinBox(parent); - spin->setRange(1, 255); - return spin; - } - case 24: // ICR校正使能(布尔) - { - QComboBox *combo = new QComboBox(parent); - combo->addItems(QStringList() << QStringLiteral(u"关闭") << QStringLiteral(u"启用")); - return combo; - } - case 25: // CRZA值 - { - QSpinBox *spin = new QSpinBox(parent); - spin->setRange(0, 1000000); // 合理范围 - return spin; - } - case 26: // ZA使能值 - { - QSpinBox *spin = new QSpinBox(parent); - spin->setRange(0, 100); - return spin; - } - default: - return new QLineEdit(parent); - } -} - -void DeviceParameterProxy::setEditorData(QWidget *editor, const QModelIndex &index) const -{ - QVariant value = index.data(Qt::EditRole); - int col = index.column(); - - switch (col) - { - case 0: // QComboBox - case 1: - case 2: - case 7: - case 24: - { - QComboBox *combo = qobject_cast(editor); - if (combo) { - int idx = combo->findText(value.toString()); - if (idx >= 0) combo->setCurrentIndex(idx); - } - break; - } - case 3: // QLineEdit(软件增益) - case 8: // QLineEdit(控制功能) - case 19: // QLineEdit(总测量时间) - { - QLineEdit *edit = qobject_cast(editor); - if (edit) edit->setText(value.toString()); - break; - } - case 4: // QDoubleSpinBox - case 6: - { - QDoubleSpinBox *spin = qobject_cast(editor); - if (spin) spin->setValue(value.toDouble()); - break; - } - case 5: // QSpinBox - case 9: - case 10: - case 11: - case 12: - case 13: - case 14: - case 15: - case 16: - case 17: - case 18: - case 20: - case 21: - case 22: - case 23: - case 25: - case 26: - { - QSpinBox *spin = qobject_cast(editor); - if (spin) spin->setValue(value.toInt()); - break; - } - default: - { - QLineEdit *edit = qobject_cast(editor); - if (edit) edit->setText(value.toString()); - break; - } - } -} - -void DeviceParameterProxy::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const -{ - int col = index.column(); - - switch (col) - { - case 0: - case 1: - case 2: - case 7: - case 24: - { - QComboBox *combo = qobject_cast(editor); - if (combo) model->setData(index, combo->currentText()); - break; - } - case 3: // 软件增益(字符串存储,因为可能超出int范围) - case 8: // 控制功能(字符串存储) - case 19: // 总测量时间(字符串存储) - { - QLineEdit *edit = qobject_cast(editor); -// if (edit) model->setData(index, edit->text()); - if (edit) { - // 提交前再次验证(防止通过回车提交无效数据) - QString text = edit->text(); - int pos = 0; - if (edit->validator() && edit->validator()->validate(text, pos) == QValidator::Acceptable) { - model->setData(index, text); - } else { - // 无效数据不写入模型,并显示提示 - QString rangeHint = edit->property("rangeHint").toString(); - QPoint pos = edit->mapToGlobal(edit->rect().topRight()); - QToolTip::showText(pos, QString("取值范围: %1").arg(rangeHint), edit); - // 焦点留在编辑器(但此时编辑器即将销毁,所以需要延迟重新打开?) - // 实际上 setModelData 被调用时编辑器即将销毁,我们无法阻止。 - // 因此更好的方法是在事件过滤器中拦截回车,避免走到这里。 - } - } - break; - } - case 4: - case 6: - { - QDoubleSpinBox *spin = qobject_cast(editor); - if (spin) model->setData(index, spin->value()); - break; - } - case 5: - case 9: - case 10: - case 11: - case 12: - case 13: - case 14: - case 15: - case 16: - case 17: - case 18: - case 20: - case 21: - case 22: - case 23: - case 25: - case 26: - { - QSpinBox *spin = qobject_cast(editor); - if (spin) model->setData(index, spin->value()); - break; - } - default: - { - QLineEdit *edit = qobject_cast(editor); - if (edit) model->setData(index, edit->text()); - break; - } - } -} - -void DeviceParameterProxy::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const -{ - editor->setGeometry(option.rect); -} - -bool DeviceParameterProxy::eventFilter(QObject *obj, QEvent *event) -{ - QLineEdit *edit = qobject_cast(obj); - if (!edit || !edit->validator()) - return QStyledItemDelegate::eventFilter(obj, event); - - if (event->type() == QEvent::FocusOut) { - QString text = edit->text(); - int pos = 0; - if (edit->validator()->validate(text, pos) != QValidator::Acceptable) { - QString rangeHint = edit->property("rangeHint").toString(); - QPoint pos = edit->mapToGlobal(edit->rect().topRight()); - QToolTip::showText(pos, QStringLiteral(u"取值范围: %1").arg(rangeHint), edit); - // 延迟重新获得焦点 - QTimer::singleShot(0, edit, SLOT(setFocus())); - return true; // 阻止焦点离开 - } else { - QToolTip::hideText(); - } - } - else if (event->type() == QEvent::KeyPress) { - QKeyEvent *keyEvent = static_cast(event); - if (keyEvent->key() == Qt::Key_Return || keyEvent->key() == Qt::Key_Enter) { - QString text = edit->text(); - int pos = 0; - if (edit->validator()->validate(text, pos) != QValidator::Acceptable) { - QString rangeHint = edit->property("rangeHint").toString(); - QPoint pos = edit->mapToGlobal(edit->rect().topRight()); - QToolTip::showText(pos, QStringLiteral(u"取值范围: %1").arg(rangeHint), edit); - return true; // 拦截回车,不提交 - } else { - QToolTip::hideText(); - // 允许回车提交,Qt 会正常处理 - } - } - } - - return QStyledItemDelegate::eventFilter(obj, event); -} diff --git a/src/DeviceParameterConfig/DeviceParameterProxy.h b/src/DeviceParameterConfig/DeviceParameterProxy.h deleted file mode 100644 index ab437d5..0000000 --- a/src/DeviceParameterConfig/DeviceParameterProxy.h +++ /dev/null @@ -1,119 +0,0 @@ -#ifndef DEVICEPARAMETERPROXY_H -#define DEVICEPARAMETERPROXY_H - -#include -#include -#include - -// ==================== 自定义验证器 ==================== - -/** - * @brief 无符号32位整数验证器(范围 0 ~ 4294967295) - */ -class UInt32Validator : public QValidator -{ -public: - UInt32Validator(QObject *parent = nullptr) : QValidator(parent) {} - - State validate(QString &input, int &pos) const override - { - if (input.isEmpty()) - return Intermediate; - - bool ok; - quint64 value = input.toULongLong(&ok); - if (!ok) - return Invalid; - - if (value <= 4294967295ULL) - return Acceptable; - - return Invalid; - } - - void fixup(QString &input) const override - { - input.clear(); - } -}; - -/** - * @brief 有符号64位整数验证器(范围 0 ~ 9223372036854775807) - * 用于总测量时间(__int64) - */ -class Int64Validator : public QValidator -{ -public: - Int64Validator(QObject *parent = nullptr) : QValidator(parent) {} - - State validate(QString &input, int &pos) const override - { - if (input.isEmpty()) - return Intermediate; - - bool ok; - qint64 value = input.toLongLong(&ok); - if (!ok) - return Invalid; - - if (value >= 0 && value <= 9223372036854775807LL) - return Acceptable; - - return Invalid; - } - - void fixup(QString &input) const override - { - input.clear(); - } -}; - -/** - * @brief 设备参数表格的代理类,用于自定义单元格的编辑器 - * - * 根据不同的列(参数类型)提供不同的编辑控件,例如下拉框、数字输入框等。 - */ -class DeviceParameterProxy : public QStyledItemDelegate -{ - Q_OBJECT -public: - explicit DeviceParameterProxy(QObject *parent = nullptr); - - /** - * @brief 创建编辑器控件,根据列索引返回不同的编辑器 - * @param parent 父窗口 - * @param option 样式选项 - * @param index 当前单元格的索引 - * @return 返回对应列的编辑器控件指针 - */ - QWidget* createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override; - - /** - * @brief 将模型中的数据设置到编辑器中 - * @param editor 编辑器控件 - * @param index 当前单元格的索引 - */ - void setEditorData(QWidget *editor, const QModelIndex &index) const override; - - /** - * @brief 将编辑器中的数据写回模型 - * @param editor 编辑器控件 - * @param model 数据模型 - * @param index 当前单元格的索引 - */ - void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override; - - /** - * @brief 更新编辑器的几何位置 - * @param editor 编辑器控件 - * @param option 样式选项 - * @param index 当前单元格的索引 - */ - void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const override; - -protected: - bool eventFilter(QObject *obj, QEvent *event) override; // 事件过滤器,用于验证输入和显示提示 -}; - - -#endif // DEVICEPARAMETERPROXY_H diff --git a/src/EnergyCountPeakFitView/EnergyCountPeakFitView.cpp b/src/EnergyCountPeakFitView/EnergyCountPeakFitView.cpp index 954afde..b93772b 100644 --- a/src/EnergyCountPeakFitView/EnergyCountPeakFitView.cpp +++ b/src/EnergyCountPeakFitView/EnergyCountPeakFitView.cpp @@ -1,18 +1,21 @@ -#define NOMINMAX - -//#include -#include -#include #include "EnergyCountPeakFitView.h" #include "CustomQwtPlot.h" +#include "PlotRectItem.h" #include "csv.h" #include +#include +#include +#include +#include #include +#include #include +#include #include #include #include #include +#include #include #include #include @@ -27,8 +30,9 @@ #include #include #include -#include +#include #include +#include #include #include #include @@ -37,6 +41,7 @@ #include "MeasureAnalysisProjectModel.h" #include "BusyIndicator.h" + QJsonObject PeakFitHistoryItem::toJson() const { QJsonObject obj; @@ -106,7 +111,7 @@ PeakFitHistoryItem PeakFitHistoryItem::fromJson(const QJsonObject& obj) return item; } -EnergyCountPeakFitView::EnergyCountPeakFitView(QWidget *parent) +EnergyCountPeakFitView::EnergyCountPeakFitView(QWidget* parent) : MeasureAnalysisView { parent } { this->setViewType(PlotFrame); @@ -123,29 +128,31 @@ EnergyCountPeakFitView::~EnergyCountPeakFitView() { LOG_DEBUG(QStringLiteral(u"%1析构.").arg(this->GetViewName())); delete _rubberBand; - clearAllSelectionRects(); - clearFitCurves(); + clearAllSelectionRects(); + clearFitCurves(); } -void EnergyCountPeakFitView::InitViewWorkspace(const QString &project_name) +void EnergyCountPeakFitView::InitViewWorkspace(const QString& project_name) { Q_UNUSED(project_name); - if (project_name.isEmpty()) return; - auto project_model = ProjectList::Instance()->GetProjectModel(project_name); - if (!project_model) return; + if (project_name.isEmpty()) + return; + auto project_model = ProjectList::Instance()->GetProjectModel(project_name); + if (!project_model) + return; - QDir project_dir(project_model->GetProjectDir()); - _workspace = project_dir.filePath(this->GetViewName()); - if (!QDir(_workspace).exists()) - project_dir.mkpath(_workspace); + QDir project_dir(project_model->GetProjectDir()); + _workspace = project_dir.filePath(this->GetViewName()); + if (!QDir(_workspace).exists()) + project_dir.mkpath(_workspace); - _historyFilePath = QDir(_workspace).filePath("peak_fit_history.json"); - loadHistoryFromFile(); + _historyFilePath = QDir(_workspace).filePath("peak_fit_history.json"); + loadHistoryFromFile(); } -void EnergyCountPeakFitView::SetAnalyzeDataFilename(const QMap &data_files_set) +void EnergyCountPeakFitView::SetAnalyzeDataFilename(const QMap& data_files_set) { - if ( !data_files_set.isEmpty() ) { + if (!data_files_set.isEmpty()) { const QString& data_name = data_files_set.firstKey(); const QString& data_filename = data_files_set.first().toString(); if (QFileInfo(data_filename).exists()) { @@ -203,9 +210,6 @@ void EnergyCountPeakFitView::setupPlot() // 启用鼠标追踪,并安装事件过滤器 _plot->canvas()->setMouseTracking(true); _plot->canvas()->installEventFilter(this); - - - } void EnergyCountPeakFitView::setupMenu() @@ -238,11 +242,12 @@ void EnergyCountPeakFitView::setupMenu() //删除当前悬停的框选区域 QAction* action_delete_hovered_rect = this->_menu->addAction(QStringLiteral(u"删除当前框选区域")); connect(action_delete_hovered_rect, &QAction::triggered, this, &EnergyCountPeakFitView::onActionDeleteHoveredRect); + QAction* action_hint = this->_menu->addAction(QStringLiteral(u"框选提示:按住 Ctrl 键并拖动左键")); action_hint->setEnabled(false); } -void EnergyCountPeakFitView::loadDataFromFile(const QString &data_name, const QString &filename) +void EnergyCountPeakFitView::loadDataFromFile(const QString& data_name, const QString& filename) { //加载新数据前清空旧数据 _currentFitRecords.clear(); @@ -274,6 +279,7 @@ void EnergyCountPeakFitView::loadDataFromFile(const QString &data_name, const QS curve->setSamples(x, y); _plot->AddCurve(curve,false); + } void EnergyCountPeakFitView::onActionCurveShowSetting() @@ -298,7 +304,7 @@ void EnergyCountPeakFitView::onActionCurveShowSetting() QVBoxLayout* checkbox_layout = new QVBoxLayout(); QHBoxLayout* checkbox_column_layout = new QHBoxLayout(); QMap curve_checkbox_map; - auto addCurveToLayout = [&](const QString& curve_name){ + auto addCurveToLayout = [&](const QString& curve_name) { QwtPlotCurve* curve = this->_plot->GetCurve(curve_name); QCheckBox* check_box = new QCheckBox(curve->title().text()); check_box->setChecked(curve->isVisible()); @@ -354,21 +360,18 @@ void EnergyCountPeakFitView::onActionCurveShowSetting() void EnergyCountPeakFitView::onActionPlotConfigure() { - } - - void EnergyCountPeakFitView::clearAllSelectionRects() { for (PlotRectItem* item : _selectionRectItems) { - if (item) { - item->detach(); - delete item; - } - } - _selectionRectItems.clear(); - _plot->replot(); + if (item) { + item->detach(); + delete item; + } + } + _selectionRectItems.clear(); + _plot->replot(); } bool EnergyCountPeakFitView::eventFilter(QObject* watched, QEvent* event) @@ -421,18 +424,20 @@ void EnergyCountPeakFitView::startSelection(const QPoint& pos) void EnergyCountPeakFitView::updateSelection(const QPoint& pos) { - if (!_rubberBand) return; - int canvasHeight = _plot->canvas()->height(); - int x1 = _selectionStart.x(); - int x2 = pos.x(); - int left = qMin(x1, x2); - int width = qAbs(x1 - x2); - _rubberBand->setGeometry(QRect(left, 0, width, canvasHeight)); + if (!_rubberBand) + return; + int canvasHeight = _plot->canvas()->height(); + int x1 = _selectionStart.x(); + int x2 = pos.x(); + int left = qMin(x1, x2); + int width = qAbs(x1 - x2); + _rubberBand->setGeometry(QRect(left, 0, width, canvasHeight)); } void EnergyCountPeakFitView::finishSelection() { if (_rubberBand) { + QRect finalRect = _rubberBand->geometry(); _rubberBand->hide(); @@ -440,13 +445,17 @@ void EnergyCountPeakFitView::finishSelection() const QwtScaleMap xMap = _plot->canvasMap(QwtPlot::xBottom); double xMin = xMap.invTransform(finalRect.left()); double xMax = xMap.invTransform(finalRect.right()); + if (xMin > xMax) std::swap(xMin, xMax); + double yMin = _plot->axisScaleDiv(QwtPlot::yLeft).lowerBound(); double yMax = _plot->axisScaleDiv(QwtPlot::yLeft).upperBound(); QRectF plotRect(xMin, yMin, xMax - xMin, yMax - yMin); + // addSelectionRect(plotRect); + // 获取曲线数据 QList curves = _plot->GetCurveList(); if (!curves.isEmpty()) { @@ -482,6 +491,7 @@ void EnergyCountPeakFitView::finishSelection() for (int i = 0; i < roiX.size(); ++i) { armaRoiX(i) = roiX[i]; armaRoiY(i) = roiY[i]; + } // 3. 执行拟合(曲线自动添加到主图) QList results = performPeakFitting(roiX, roiY/*, &userP0*/); @@ -510,29 +520,28 @@ void EnergyCountPeakFitView::finishSelection() _isSelecting = false; } - - -void EnergyCountPeakFitView::addSelectionRect(const QRectF &plotRect) +void EnergyCountPeakFitView::addSelectionRect(const QRectF& plotRect) { PlotRectItem* rectItem = new PlotRectItem("Selection"); - rectItem->setAxes(QwtPlot::xBottom, QwtPlot::yLeft); - rectItem->setRect(plotRect); - // 设置填充为透明(无填充) - rectItem->setBrush(QBrush(Qt::transparent)); // 或 Qt::NoBrush - // 设置边框颜色为红色,线宽2 - rectItem->setPen(QPen(Qt::red, 2)); - rectItem->setSelectionType("current"); - rectItem->setSelectionIndex(_selectionRectItems.size()); - rectItem->attach(_plot); - _selectionRectItems.append(rectItem); - _plot->replot(); + rectItem->setAxes(QwtPlot::xBottom, QwtPlot::yLeft); + rectItem->setRect(plotRect); + // 设置填充为透明(无填充) + rectItem->setBrush(QBrush(Qt::transparent)); // 或 Qt::NoBrush + // 设置边框颜色为红色,线宽2 + rectItem->setPen(QPen(Qt::red, 2)); + rectItem->setSelectionType("current"); + rectItem->setSelectionIndex(_selectionRectItems.size()); + rectItem->attach(_plot); + _selectionRectItems.append(rectItem); + _plot->replot(); + } void EnergyCountPeakFitView::fadeSelectionRectBorders() { for (PlotRectItem* item : _selectionRectItems) { if (item) { - QPen fadedPen(Qt::red, 1, Qt::DashLine); // 可根据原样式调整 + QPen fadedPen(Qt::red, 1, Qt::DashLine); // 可根据原样式调整 item->setPen(fadedPen); } } @@ -618,7 +627,7 @@ QList EnergyCountPeakFitView::performPeakFitting(const QVector xs, ys,ysTw; @@ -1129,7 +1138,7 @@ void EnergyCountPeakFitView::onActionDeleteHoveredRect() return; } - // 【修改】使用新接口获取类型和索引 + //使用新接口获取类型和索引 QString rectType = _hoveredRectItem->selectionType(); int rectIndex = _hoveredRectItem->selectionIndex(); diff --git a/src/GlobalDefine.h b/src/GlobalDefine.h index 955a506..f3d699a 100644 --- a/src/GlobalDefine.h +++ b/src/GlobalDefine.h @@ -10,7 +10,7 @@ // 转换Qt字符串路径为系统编码的C字符串(解决中文路径问题) static const char* QStrToSysPath(const QString& qstr_path) { - static std::string sys_path; // 静态变量避免内存释放 + std::string sys_path; // 静态变量避免内存释放 #ifdef Q_OS_WIN // Windows:转为GBK编码 QTextCodec* gbkCodec = QTextCodec::codecForName("GBK"); diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp index 06ebef4..5fa886c 100644 --- a/src/MainWindow.cpp +++ b/src/MainWindow.cpp @@ -21,13 +21,13 @@ #include "EnergyScaleForm.h" #include "MeasureAnalysisHistoryForm.h" #include "MeasureAnalysisProjectModel.h" -#include "MeasureDeviceParamsCfgForm.h" #include "NewMeasureAnalysisDlg.h" #include "MeasureAnalysisView.h" #include "MeasureAnalysisTreeView.h" #include "GlobalDefine.h" -#include "DeviceParameterConfig.h" +#include "DeviceParamsManagerDlg.h" #include "NuclideLib.h" + using namespace ads; MainWindow* MainWindow::_s_main_win = nullptr; @@ -220,18 +220,11 @@ void MainWindow::initAction() } } }); - connect(ui->action_manage_measurement_analysis, &QAction::triggered, this->_action_central_dock_widget, &QAction::triggered); + connect(ui->action_manage_measurement_analysis, &QAction::triggered, [this](){ + this->_action_central_dock_widget->triggered(true); + }); connect(ui->action_device_config_mrg, &QAction::triggered, []() { - QDialog device_cfg_mrg_dlg; - device_cfg_mrg_dlg.setObjectName("MeasureDeviceParamsCfgFormDlg"); - device_cfg_mrg_dlg.setWindowTitle(QStringLiteral(u"测量设备参数配置管理")); - device_cfg_mrg_dlg.setWindowFlags(device_cfg_mrg_dlg.windowFlags() | Qt::WindowMaximizeButtonHint); -// MeasureDeviceParamsCfgForm* measure_dev_params_cfg_form = new MeasureDeviceParamsCfgForm(&device_cfg_mrg_dlg); - DeviceParameterConfig * measure_dev_params_cfg_form = new DeviceParameterConfig(&device_cfg_mrg_dlg); - QHBoxLayout* hlayout = new QHBoxLayout; - hlayout->addWidget(measure_dev_params_cfg_form); - device_cfg_mrg_dlg.setLayout(hlayout); - device_cfg_mrg_dlg.exec(); + DeviceParamsManagerDlg().exec(); }); connect(ui->action_energy_scale_mrg, &QAction::triggered, []() { QDialog energy_scale_mrg_dlg; diff --git a/src/MeasureAnalysisHistoryForm/MeasureAnalysisHistoryForm.cpp b/src/MeasureAnalysisHistoryForm/MeasureAnalysisHistoryForm.cpp index 61fc3f0..574569d 100644 --- a/src/MeasureAnalysisHistoryForm/MeasureAnalysisHistoryForm.cpp +++ b/src/MeasureAnalysisHistoryForm/MeasureAnalysisHistoryForm.cpp @@ -46,7 +46,7 @@ void MeasureAnalysisHistoryForm::loadHistoryInfo(const QString &history_name) if (!projects_dir.exists()) { return; } - QList project_dirs = projects_dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot, QDir::Time); + QList project_dirs = projects_dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot | QDir::NoSymLinks, QDir::Time); for (const QString& project_dir : project_dirs) { QDir project_dir_path(projects_dir.filePath(project_dir)); if (project_dir_path.exists()) { @@ -147,7 +147,7 @@ void MeasureAnalysisHistoryForm::onRemoveSelectedProject() } } if (selected_project_list.isEmpty()) { - QMessageBox::information(this, QStringLiteral(u"确认"), QStringLiteral(u"请选择想要删除的测量分析项目!")); + QMessageBox::information(this, QStringLiteral(u"提示"), QStringLiteral(u"请选择想要删除的测量分析项目!")); return; } if (QMessageBox::No == QMessageBox::question(this, QStringLiteral(u"确认"), QStringLiteral(u"是否删除选择的测量分析项目?"))) { diff --git a/src/MeasureAnalysisProjectModel.cpp b/src/MeasureAnalysisProjectModel.cpp index 00505ba..36164a1 100644 --- a/src/MeasureAnalysisProjectModel.cpp +++ b/src/MeasureAnalysisProjectModel.cpp @@ -113,6 +113,16 @@ void MeasureAnalysisProjectModel::SetTimeWinConformEnergyData(uint time_win, uin this->_time_win_conform_energy_data[time_win][conform_particle_count] = filename; } +void MeasureAnalysisProjectModel::SetAntiConformParticleData(uint time_win, const QString &filename) +{ + this->_anti_conform_particle_data[time_win] = filename; +} + +void MeasureAnalysisProjectModel::SetAntiConformEnergyData(uint time_win, const QString &filename) +{ + this->_anti_conform_energy_data[time_win] = filename; +} + void MeasureAnalysisProjectModel::SetAnalysisCustomData(AnalysisType analysis_type, const QString &data_item_name, const QString &data_filename) { this->_analysis_custom_data_set[analysis_type][data_item_name] = data_filename; @@ -259,6 +269,26 @@ const QMap MeasureAnalysisProjectModel::GetTimeWinConformEnergyDa return conform_energy_data; } +const QMap &MeasureAnalysisProjectModel::GetAntiConformParticleData() +{ + return _anti_conform_particle_data; +} + +const QString &MeasureAnalysisProjectModel::GetAntiConformParticleData(uint time_win) +{ + return _anti_conform_particle_data.value(time_win); +} + +const QMap &MeasureAnalysisProjectModel::GetAntiConformEnergyData() +{ + return _anti_conform_energy_data; +} + +const QString &MeasureAnalysisProjectModel::GetAntiConformEnergyData(uint time_win) +{ + return _anti_conform_energy_data.value(time_win); +} + const QString MeasureAnalysisProjectModel::GetAnalysisCustomData(AnalysisType analysis_type, const QString &data_item_name) { return this->_analysis_custom_data_set.value(analysis_type).value(data_item_name); @@ -403,6 +433,16 @@ bool MeasureAnalysisProjectModel::LoadProjectModel(const QString& project_filena this->_time_win_conform_energy_data[time_win] = conform_energy_data; } + const auto& anti_conform_particle_data = model_data["AntiConformParticleData"].toMap(); + for (auto it = anti_conform_particle_data.constBegin(); it!=anti_conform_particle_data.constEnd(); ++it) { + this->_anti_conform_particle_data[it.key().toUInt()] = ProjectAbsFilename(it.value().toString()); + } + + const auto& anti_conform_energy_data = model_data["AntiConformEnergyData"].toMap(); + for (auto it = anti_conform_energy_data.constBegin(); it!=anti_conform_energy_data.constEnd(); ++it) { + this->_anti_conform_energy_data[it.key().toUInt()] = ProjectAbsFilename(it.value().toString()); + } + return true; } @@ -473,6 +513,18 @@ bool MeasureAnalysisProjectModel::SaveProjectModel() } project_json_obj_map["TimeWinConformEnergyData"] = time_win_conform_energy_data; + QVariantMap anti_conform_particle_data; + for (auto it = this->_anti_conform_particle_data.constBegin(); it != this->_anti_conform_particle_data.constEnd(); ++it) { + anti_conform_particle_data[QString::number(it.key())] = ProjectRelativeFilename(it.value()); + } + project_json_obj_map["AntiConformParticleData"] = anti_conform_particle_data; + + QVariantMap anti_conform_energy_data; + for (auto it = this->_anti_conform_energy_data.constBegin(); it != this->_anti_conform_energy_data.constEnd(); ++it) { + anti_conform_energy_data[QString::number(it.key())] = ProjectRelativeFilename(it.value()); + } + project_json_obj_map["AntiConformEnergyData"] = anti_conform_energy_data; + // 将项目模型保存到json文件 QJsonDocument json_doc = QJsonDocument::fromVariant(project_json_obj_map); QFile json_file(this->_project_filename); @@ -548,6 +600,7 @@ bool MeasureAnalysisProjectModelList::RmProjectModel(const QString& project_name return false; } } + emit removedProjectModel(project_name); if (_project_models.contains(project_name)) { delete _project_models[project_name]; _project_models.remove(project_name); @@ -557,7 +610,6 @@ bool MeasureAnalysisProjectModelList::RmProjectModel(const QString& project_name const QString& project_name = project_model->GetProjectName(); SetCurrentProjectModel(project_name); } - emit removedProjectModel(project_name); return true; } @@ -743,6 +795,10 @@ void MeasureAnalysisProjectModelList::ApplyEnergyScale(const QString &project_na auto coincidence_process_task = new DataProcessWorkPool::EnergyScaleCoincidenceDataTask; coincidence_process_task->SetFinishedNotifier(this, "onEnergyScaleCoincidenceDataFinished", project_name); coincidence_process_task->StartTask(); + + auto anti_coincidence_process_task = new DataProcessWorkPool::EnergyScaleaAntiCoincidenceDataTask; + anti_coincidence_process_task->SetFinishedNotifier(this, "onEnergyScaleAntiCoincidenceDataFinished", project_name); + anti_coincidence_process_task->StartTask(); } } } @@ -954,11 +1010,6 @@ void MeasureAnalysisProjectModelList::onEnergyScaleCoincidenceDataFinished(bool auto energy_total_count_spec_item = node_map[item_name]; this->SetNodeStatus(energy_total_count_spec_item, status, status_ok); } - item_name = QStringLiteral(u"反符合能谱[%1ns]").arg(conform_time_win); - if (node_map.contains(item_name)) { - auto energy_total_count_spec_item = node_map[item_name]; - this->SetNodeStatus(energy_total_count_spec_item, status, status_ok); - } item_name = QStringLiteral(u"二维符合能谱[%1ns]").arg(conform_time_win); if (node_map.contains(item_name)) { auto energy_total_count_spec_item = node_map[item_name]; @@ -977,6 +1028,33 @@ void MeasureAnalysisProjectModelList::onEnergyScaleCoincidenceDataFinished(bool } } +void MeasureAnalysisProjectModelList::onEnergyScaleAntiCoincidenceDataFinished(bool ok, const QString &project_name, const QVariant &data) +{ + Q_UNUSED(data); + if ( !ok ) + return; + if (this->_project_models.contains(project_name)) { + auto pro_model = this->_project_models[project_name]; + auto& node_map = this->_project_node_items[project_name]; + const auto& anti_conform_energy_data = pro_model->GetAntiConformEnergyData(); + for (const auto& time_win : anti_conform_energy_data.keys()) { + bool status_ok = false; + QString status = QStringLiteral(u"无效"); + const QString& data_filename = anti_conform_energy_data.value(time_win); + if ( (!data_filename.isEmpty()) && QFile::exists(data_filename) ) { + status_ok = true; + status = QStringLiteral(u"有效"); + } + QString item_name = QStringLiteral(u"反符合能谱[%1ns]").arg(time_win); + if (node_map.contains(item_name)) { + auto anti_conform_erergy_spec_item = node_map[item_name]; + this->SetNodeStatus(anti_conform_erergy_spec_item, status, status_ok); + } + } + pro_model->SaveProjectModel(); + } +} + void MeasureAnalysisProjectModelList::intiProjectNodeStruce(MeasureAnalysisProjectModel* pro_model) { if (!pro_model) { diff --git a/src/MeasureAnalysisProjectModel.h b/src/MeasureAnalysisProjectModel.h index 317c8c1..5a2d845 100644 --- a/src/MeasureAnalysisProjectModel.h +++ b/src/MeasureAnalysisProjectModel.h @@ -39,6 +39,8 @@ public: void SetParticleEnergyDataFilename(const QString& filename); void SetTimeWinConformParticleData(uint time_win, uint conform_particle_count, const QString& filename); void SetTimeWinConformEnergyData(uint time_win, uint conform_particle_count, const QString& filename); + void SetAntiConformParticleData(uint time_win, const QString& filename); + void SetAntiConformEnergyData(uint time_win, const QString& filename); void SetAnalysisCustomData(AnalysisType analysis_type, const QString& data_item_name, const QString& data_filename); const QString& GetProjectDir() const; @@ -63,6 +65,10 @@ public: const QMap GetTimeWinConformParticleDataFilenameList(uint time_win) const; const QMap > GetConformParticleEnergyDataFilenameList() const; const QMap GetTimeWinConformEnergyDataFilenameList(uint time_win) const; + const QMap& GetAntiConformParticleData(); + const QString& GetAntiConformParticleData(uint time_win); + const QMap& GetAntiConformEnergyData(); + const QString& GetAntiConformEnergyData(uint time_win); const QString GetAnalysisCustomData(AnalysisType analysis_type, const QString& data_item_name); void SetDeviceGuid(const QString& device_guid); @@ -96,6 +102,9 @@ private: QString _particle_energy_data_filename; QMap > _time_win_conform_particle_data; QMap > _time_win_conform_energy_data; + QMap _anti_conform_particle_data; + QMap _anti_conform_energy_data; + QMap > _analysis_custom_data_set; QString _device_guid; @@ -160,6 +169,7 @@ private slots: void onEnergyCountProcessFinished(bool ok, const QString& project_name, const QVariant& data); void onCoincidenceProcessFinished(bool ok, const QString& project_name, const QVariant& data); void onEnergyScaleCoincidenceDataFinished(bool ok, const QString& project_name, const QVariant& data); + void onEnergyScaleAntiCoincidenceDataFinished(bool ok, const QString& project_name, const QVariant& data); signals: void removedProjectModel(const QString& project_name); diff --git a/src/MeasureAnalysisTreeView.cpp b/src/MeasureAnalysisTreeView.cpp index e554378..460de7f 100644 --- a/src/MeasureAnalysisTreeView.cpp +++ b/src/MeasureAnalysisTreeView.cpp @@ -269,6 +269,13 @@ void MeasureAnalysisTreeView::onNodeDoubleClicked(const QModelIndex& index) } } } break; + case AnalysisType::AntiCoincidenceSpectrumView: { + MeasureAnalysisProjectModel* project_model = _model->GetProjectModel(project_name); + if (project_model) { + auto file_name = project_model->GetAntiConformEnergyData(project_model->GetConformTimeWin()); + data_files_set[QStringLiteral(u"反符合粒子数据")] = file_name; + } + } break; default: break; } diff --git a/src/MeasureAnalysisView.cpp b/src/MeasureAnalysisView.cpp index 66708cd..de1c907 100644 --- a/src/MeasureAnalysisView.cpp +++ b/src/MeasureAnalysisView.cpp @@ -10,6 +10,7 @@ #include "ParticleTimeDifferenceView.h" #include "TwoDSpectralCompliance.h" #include "ConformToTheEnergySpectrum.h" +#include "AntiConformEnergySpectrumView.h" #include MeasureAnalysisView* MeasureAnalysisView::NewAnalyzeView(AnalysisType view_type) @@ -101,8 +102,8 @@ MeasureAnalysisView* MeasureAnalysisView::NewAnalyzeView(AnalysisType view_type) new_view->setDeleteOnClose(false); } break; case AnalysisType::AntiCoincidenceSpectrumView: { - // new_view = new MeasureAnalysisDataTableView; - // new_view->setDeleteOnClose(false); + new_view = new AntiConformEnergySpectrumView; + new_view->setDeleteOnClose(false); } break; default: break; diff --git a/src/MeasureDeviceParamsCfgForm.cpp b/src/MeasureDeviceParamsCfgForm.cpp deleted file mode 100644 index c365cc3..0000000 --- a/src/MeasureDeviceParamsCfgForm.cpp +++ /dev/null @@ -1,14 +0,0 @@ -#include "MeasureDeviceParamsCfgForm.h" -#include "ui_MeasureDeviceParamsCfgForm.h" - -MeasureDeviceParamsCfgForm::MeasureDeviceParamsCfgForm(QWidget *parent) - : QWidget(parent) - , ui(new Ui::MeasureDeviceParamsCfgForm) -{ - ui->setupUi(this); -} - -MeasureDeviceParamsCfgForm::~MeasureDeviceParamsCfgForm() -{ - delete ui; -} diff --git a/src/MeasureDeviceParamsCfgForm.h b/src/MeasureDeviceParamsCfgForm.h deleted file mode 100644 index ceb3468..0000000 --- a/src/MeasureDeviceParamsCfgForm.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef MEASUREDEVICEPARAMSCFGFORM_H -#define MEASUREDEVICEPARAMSCFGFORM_H - -#include - -namespace Ui { -class MeasureDeviceParamsCfgForm; -} - -class MeasureDeviceParamsCfgForm : public QWidget -{ - Q_OBJECT - -public: - explicit MeasureDeviceParamsCfgForm(QWidget *parent = nullptr); - ~MeasureDeviceParamsCfgForm(); - -private: - Ui::MeasureDeviceParamsCfgForm *ui; -}; - -#endif // MEASUREDEVICEPARAMSCFGFORM_H diff --git a/src/MeasureDeviceParamsCfgForm.ui b/src/MeasureDeviceParamsCfgForm.ui deleted file mode 100644 index 1eb1f61..0000000 --- a/src/MeasureDeviceParamsCfgForm.ui +++ /dev/null @@ -1,317 +0,0 @@ - - - MeasureDeviceParamsCfgForm - - - - 0 - 0 - 1453 - 806 - - - - 测量设备参数配置 - - - - - - 设备参数配置列表 - - - - - - - 0 - 0 - - - - - - - - - - 添加 - - - - - - - 删除 - - - - - - - - - - - - - - - - - 60 - 0 - - - - 配置命名: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - - - 保存到测量分析 - - - - - - - 保存到设备参数配置管理 - - - - - - - - - - - - 60 - 0 - - - - 备注说明: - - - Qt::AlignRight|Qt::AlignTop|Qt::AlignTrailing - - - - - - - - 0 - 0 - - - - - 16777215 - 50 - - - - - - - - - - true - - - - 通道1 - - - - - 通道2 - - - - - 通道3 - - - - - 通道4 - - - - - 通道5 - - - - - 通道6 - - - - - 通道7 - - - - - 通道8 - - - - - 通道9 - - - - - 通道10 - - - - - 通道11 - - - - - 通道12 - - - - - 通道13 - - - - - 通道14 - - - - - 通道15 - - - - - 通道16 - - - - - 通道17 - - - - - 通道18 - - - - - 通道19 - - - - - 通道20 - - - - - 通道21 - - - - - 通道22 - - - - - 时间常数 - - - - - 上升时间 - - - - - 平顶时间 - - - - - 触发阈值 - - - - - 直流偏移 - - - - - 恢复速度 - - - - - 滤波参数 - - - - - 输入信号正负 - - - - - LFR - - - - - 保护时间 - - - - - 硬件增益 - - - - - 软件增益 - - - - - 谱线道数 - - - - - - - - - - - diff --git a/src/MeasureDeviceParamsConfigView/DeviceParamsManagerDlg.cpp b/src/MeasureDeviceParamsConfigView/DeviceParamsManagerDlg.cpp new file mode 100644 index 0000000..b2741ab --- /dev/null +++ b/src/MeasureDeviceParamsConfigView/DeviceParamsManagerDlg.cpp @@ -0,0 +1,143 @@ +#include "DeviceParamsManagerDlg.h" +#include "ui_DeviceParamsManagerDlg.h" +#include +#include "GlobalDefine.h" +#include "DeviceParamsSaveToSysDlg.h" +#include + +DeviceParamsManagerDlg::DeviceParamsManagerDlg(QWidget *parent) + : QDialog(parent) + , ui(new Ui::DeviceParamsManagerDlg) +{ + ui->setupUi(this); + this->setWindowFlags(this->windowFlags() & ~Qt::WindowContextHelpButtonHint); + this->setWindowFlags(this->windowFlags() | Qt::WindowMinMaxButtonsHint); + + scanParamsCfgFiles(); + + connect(ui->listw_cfg_list, &QListWidget::currentItemChanged, this, &DeviceParamsManagerDlg::onCfgListCurrentItemChanged); + connect(ui->btn_new, &QPushButton::clicked, this, &DeviceParamsManagerDlg::onBtnNew); + connect(ui->btn_delete, &QPushButton::clicked, this, &DeviceParamsManagerDlg::onBtnDelete); + connect(ui->btn_save, &QPushButton::clicked, this, &DeviceParamsManagerDlg::onBtnSave); +} + +DeviceParamsManagerDlg::~DeviceParamsManagerDlg() +{ + delete ui; +} + +void DeviceParamsManagerDlg::scanParamsCfgFiles() +{ + ui->params_table_form->SetButtonEnable(false); + ui->listw_cfg_list->clear(); + // 遍历可执行文件目录下Projects目录下的所有文件夹,找出所有项目文件夹下的.msproject文件 + const QString& device_params_dir_path = QDir(qApp->applicationDirPath()).filePath("configure/DeviceParams"); + QDir device_params_dir(device_params_dir_path); + if (!device_params_dir.exists(device_params_dir_path)) { + LOG_WARN(QStringLiteral(u"系统测量参数配置管理目录不存在:%1").arg(device_params_dir_path)); + return; + } + QList ms_cfg_basenames = device_params_dir.entryList(QDir::Files | QDir::NoDotAndDotDot | QDir::NoSymLinks, QDir::Time); + for (const QString& ms_cfg_basename : ms_cfg_basenames) { + const QString& ms_cfg_filename = device_params_dir.filePath(ms_cfg_basename); + QFileInfo ms_cfg_file_info(ms_cfg_filename); + if ("mscfg" == ms_cfg_file_info.suffix()) { + QListWidgetItem* item = new QListWidgetItem(ms_cfg_file_info.baseName()); + item->setData(Qt::UserRole, ms_cfg_filename); + ui->listw_cfg_list->addItem(item); + } + } + const QString cfg_name = ui->linedit_cfg_name->text(); + if (!cfg_name.isEmpty()) { + QList items = ui->listw_cfg_list->findItems(cfg_name, Qt::MatchExactly); + QListWidgetItem* current_item = items.first(); + if (current_item) { + ui->listw_cfg_list->setCurrentItem(current_item); + } + } +} + +void DeviceParamsManagerDlg::onBtnNew() +{ + DeviceParamsSaveToSysDlg params_save_to_sys_dlg; + if (QDialog::Accepted == params_save_to_sys_dlg.exec()) { + const QString& device_params_dir_path = QDir(qApp->applicationDirPath()).filePath("configure/DeviceParams"); + const QString cfg_name = params_save_to_sys_dlg.GetCfgName(); + const QString cfg_description = params_save_to_sys_dlg.GetCfgDescription(); + const QString params_cfg_filename = QDir(device_params_dir_path).filePath(cfg_name) + ".mscfg"; + if (ui->params_table_form->SaveSelectedChannelConfig(params_cfg_filename, cfg_name, cfg_description)) { + QListWidgetItem* item = new QListWidgetItem(cfg_name); + item->setData(Qt::UserRole, params_cfg_filename); + ui->listw_cfg_list->addItem(item); + ui->listw_cfg_list->setCurrentItem(item); + } + } +} + +void DeviceParamsManagerDlg::onBtnDelete() +{ + QListWidgetItem *current = ui->listw_cfg_list->currentItem(); + if (current) { + const QString& ms_cfg_filename = current->data(Qt::UserRole).toString(); + if (!ms_cfg_filename.isEmpty()) { + if (QMessageBox::No == QMessageBox::question(this, QStringLiteral(u"确认"), QStringLiteral(u"是否删除选择的测量参数配置?"))) { + return; + } + QFile ms_cfg_file(ms_cfg_filename); + if (!ms_cfg_file.remove()) { + LOG_WARN(QStringLiteral(u"删除设备测量参数配置[%1]失败: %2").arg(current->text()).arg(ms_cfg_file.errorString())); + } else { + ui->listw_cfg_list->removeItemWidget(current); + ui->linedit_cfg_name->clear(); + ui->pte_description->clear(); + ui->params_table_form->ClearParamsTable(); + } + } + } +} + +void DeviceParamsManagerDlg::onBtnSave() +{ + const QString& device_params_dir_path = QDir(qApp->applicationDirPath()).filePath("configure/DeviceParams"); + const QString cfg_name = ui->linedit_cfg_name->text(); + if (cfg_name.isEmpty()) { + QMessageBox::warning(this, QStringLiteral(u"警告"), QStringLiteral(u"测量参数配置名称不能为空!")); + return; + } + const QString cfg_description = ui->pte_description->toPlainText(); + const QString cfg_filename = QDir(device_params_dir_path).filePath(cfg_name) + ".mscfg"; + if (QFile::exists(cfg_filename)) { + QListWidgetItem *current = ui->listw_cfg_list->currentItem(); + if (current) { + const QString& ms_cfg_filename = current->data(Qt::UserRole).toString(); + if (!ms_cfg_filename.isEmpty()) { + QFile ms_cfg_file(ms_cfg_filename); + if (!ms_cfg_file.remove()) { + LOG_WARN(QStringLiteral(u"删除设备测量参数配置[%1]失败: %2").arg(current->text()).arg(ms_cfg_file.errorString())); + } + } + } + } + if (ui->params_table_form->SaveSelectedChannelConfig(cfg_filename, cfg_name, cfg_description)) { + QListWidgetItem* current = ui->listw_cfg_list->currentItem(); + if (current) { + current->setText(cfg_name); + current->setData(Qt::UserRole, cfg_filename); + } + } + this->scanParamsCfgFiles(); +} + +void DeviceParamsManagerDlg::onCfgListCurrentItemChanged(QListWidgetItem *current) +{ + if (current) { + const QString& ms_cfg_filename = current->data(Qt::UserRole).toString(); + if (!ms_cfg_filename.isEmpty()) { + ui->params_table_form->SetConfigFilename(ms_cfg_filename); + ui->linedit_cfg_name->clear(); + ui->pte_description->clear(); + ui->linedit_cfg_name->setText(ui->params_table_form->GetConfigName()); + ui->pte_description->setPlainText(ui->params_table_form->GetConfigDescription()); + } + } +} diff --git a/src/MeasureDeviceParamsConfigView/DeviceParamsManagerDlg.h b/src/MeasureDeviceParamsConfigView/DeviceParamsManagerDlg.h new file mode 100644 index 0000000..825163f --- /dev/null +++ b/src/MeasureDeviceParamsConfigView/DeviceParamsManagerDlg.h @@ -0,0 +1,33 @@ +#ifndef DEVICEPARAMSMANAGERDLG_H +#define DEVICEPARAMSMANAGERDLG_H + +#include + +namespace Ui { +class DeviceParamsManagerDlg; +} + +class QListWidgetItem; + +class DeviceParamsManagerDlg : public QDialog +{ + Q_OBJECT + +public: + explicit DeviceParamsManagerDlg(QWidget *parent = nullptr); + ~DeviceParamsManagerDlg(); + +private: + void scanParamsCfgFiles(); + +private slots: + void onBtnNew(); + void onBtnDelete(); + void onBtnSave(); + void onCfgListCurrentItemChanged(QListWidgetItem *current); + +private: + Ui::DeviceParamsManagerDlg *ui; +}; + +#endif // DEVICEPARAMSMANAGERDLG_H diff --git a/src/MeasureDeviceParamsConfigView/DeviceParamsManagerDlg.ui b/src/MeasureDeviceParamsConfigView/DeviceParamsManagerDlg.ui new file mode 100644 index 0000000..1c50ad4 --- /dev/null +++ b/src/MeasureDeviceParamsConfigView/DeviceParamsManagerDlg.ui @@ -0,0 +1,143 @@ + + + DeviceParamsManagerDlg + + + + 0 + 0 + 1075 + 712 + + + + 设备测量参数管理 + + + + + + + + + + + + 设备测量参数配置列表 + + + + + + + + 0 + 0 + + + + + + + + + + 新建配置 + + + + + + + 删除配置 + + + + + + + + + + + + + + + + + + + + 测量参数配置名称: + + + + + + + + + + 保存 + + + + + + + + + + + 测量参数配置说明: + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + + + + + + 0 + 0 + + + + + 16777215 + 50 + + + + + + + + + + + 0 + 0 + + + + + + + + + + + + DeviceParamsTableForm + QWidget +
DeviceParamsTableForm.h
+ 1 +
+
+ + +
diff --git a/src/MeasureDeviceParamsConfigView/DeviceParamsSaveToSysDlg.cpp b/src/MeasureDeviceParamsConfigView/DeviceParamsSaveToSysDlg.cpp new file mode 100644 index 0000000..47ef5fc --- /dev/null +++ b/src/MeasureDeviceParamsConfigView/DeviceParamsSaveToSysDlg.cpp @@ -0,0 +1,46 @@ +#include "DeviceParamsSaveToSysDlg.h" +#include "ui_DeviceParamsSaveToSysDlg.h" +#include +#include + +DeviceParamsSaveToSysDlg::DeviceParamsSaveToSysDlg(QWidget *parent) + : QDialog(parent) + , ui(new Ui::DeviceParamsSaveToSysDlg) +{ + ui->setupUi(this); + this->setWindowFlags(this->windowFlags() & ~Qt::WindowContextHelpButtonHint); + + connect(ui->btn_cancel, &QPushButton::clicked, this, &DeviceParamsSaveToSysDlg::reject); + connect(ui->btn_ok, &QPushButton::clicked, this, &DeviceParamsSaveToSysDlg::onBtnOkClicked); +} + +DeviceParamsSaveToSysDlg::~DeviceParamsSaveToSysDlg() +{ + delete ui; +} + +QString DeviceParamsSaveToSysDlg::GetCfgName() +{ + return ui->linedit_name->text(); +} + +QString DeviceParamsSaveToSysDlg::GetCfgDescription() +{ + return ui->pte_description->toPlainText(); +} + +void DeviceParamsSaveToSysDlg::onBtnOkClicked() +{ + const QString& cfg_name = ui->linedit_name->text(); + if (cfg_name.isEmpty()) { + QMessageBox::warning(this, QStringLiteral(u"警告"), QStringLiteral(u"测量参数配置名称不能为空!")); + return; + } + const QString& device_params_dir_path = QDir(qApp->applicationDirPath()).filePath("configure/DeviceParams"); + const QString ms_cfg_name = cfg_name + QString(".mscfg"); + if (QDir(device_params_dir_path).exists(ms_cfg_name)) { + QMessageBox::warning(this, QStringLiteral(u"警告"), QStringLiteral(u"测量参数配置名称\"%1\"已存在!").arg(cfg_name)); + return; + } + this->accept(); +} diff --git a/src/MeasureDeviceParamsConfigView/DeviceParamsSaveToSysDlg.h b/src/MeasureDeviceParamsConfigView/DeviceParamsSaveToSysDlg.h new file mode 100644 index 0000000..4b11fc5 --- /dev/null +++ b/src/MeasureDeviceParamsConfigView/DeviceParamsSaveToSysDlg.h @@ -0,0 +1,28 @@ +#ifndef DEVICEPARAMSSAVETOSYSDLG_H +#define DEVICEPARAMSSAVETOSYSDLG_H + +#include + +namespace Ui { +class DeviceParamsSaveToSysDlg; +} + +class DeviceParamsSaveToSysDlg : public QDialog +{ + Q_OBJECT + +public: + explicit DeviceParamsSaveToSysDlg(QWidget *parent = nullptr); + ~DeviceParamsSaveToSysDlg(); + + QString GetCfgName(); + QString GetCfgDescription(); + +private slots: + void onBtnOkClicked(); + +private: + Ui::DeviceParamsSaveToSysDlg *ui; +}; + +#endif // DEVICEPARAMSSAVETOSYSDLG_H diff --git a/src/MeasureDeviceParamsConfigView/DeviceParamsSaveToSysDlg.ui b/src/MeasureDeviceParamsConfigView/DeviceParamsSaveToSysDlg.ui new file mode 100644 index 0000000..1c25a07 --- /dev/null +++ b/src/MeasureDeviceParamsConfigView/DeviceParamsSaveToSysDlg.ui @@ -0,0 +1,83 @@ + + + DeviceParamsSaveToSysDlg + + + + 0 + 0 + 512 + 229 + + + + 测量设备参数信息 + + + + + + + + 测量参数配置名称: + + + + + + + + + + + + + + 测量参数配置说明: + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + 保存到系统 + + + + + + + 取消 + + + + + + + + + + diff --git a/src/MeasureDeviceParamsConfigView/DeviceParamsTableForm.cpp b/src/MeasureDeviceParamsConfigView/DeviceParamsTableForm.cpp index d865761..1c3342b 100644 --- a/src/MeasureDeviceParamsConfigView/DeviceParamsTableForm.cpp +++ b/src/MeasureDeviceParamsConfigView/DeviceParamsTableForm.cpp @@ -9,6 +9,17 @@ #include #include #include +#include +#include +#include "DeviceParamsSaveToSysDlg.h" + +static QStringList s_addr_count_list { "256", "512", "1024", "2048", "4096", "8192", "16384" }; +static QMap s_transfer_mode_list { + { 1, QStringLiteral(u"波形模式") }, + { 2, QStringLiteral(u"ADC模式") }, + { 3, QStringLiteral(u"粒子模式") } +}; +static QStringList s_device_gain_list { "1", "2", "4", "8", "16" }; DeviceParamsItemDelegate::DeviceParamsItemDelegate(QObject* parent) : QStyledItemDelegate(parent) @@ -21,52 +32,66 @@ QWidget* DeviceParamsItemDelegate::createEditor(QWidget* parent, const QStyleOpt int col = index.column(); switch (col) { case 1: { // 多道分辨率 - QStringList value_list { "256", "512", "1024", "2048", "4096", "8192", "16384" }; QComboBox *combobox = new QComboBox(parent); - for (int index = 0; index < value_list.size(); ++index) { - QString value = value_list.at(index); + for (int index = 0; index < s_addr_count_list.size(); ++index) { + QString value = s_addr_count_list.at(index); combobox->addItem(value); } editor = combobox; } break; - case 2: { // 硬件增益 - QStringList value_list { "1", "2", "4", "8", "16" }; + case 2: { // 数据模式 QComboBox *combobox = new QComboBox(parent); - for (int index = 0; index < value_list.size(); ++index) { - QString value = value_list.at(index); + QList transfer_mode_list = s_transfer_mode_list.keys(); + qSort(transfer_mode_list.rbegin(), transfer_mode_list.rend()); + foreach (int transfer_mode, transfer_mode_list) { + combobox->addItem(s_transfer_mode_list.value(transfer_mode), transfer_mode); + } + editor = combobox; + } break; + case 3: { // 硬件增益 + QComboBox *combobox = new QComboBox(parent); + for (int index = 0; index < s_device_gain_list.size(); ++index) { + QString value = s_device_gain_list.at(index); combobox->addItem(value, index + 1); } editor = combobox; } break; - case 3: { // 软件增益 + case 4: { // 软件增益 QSpinBox* spinbox = new QSpinBox(parent); spinbox->setRange(1, 2^32-1); editor = spinbox; } break; - case 4: { // 时间常数 - QSpinBox* spinbox = new QSpinBox(parent); + case 5: { // 时间常数 + QDoubleSpinBox* spinbox = new QDoubleSpinBox(parent); spinbox->setRange(1, 100); editor = spinbox; } break; - case 5: { // 直流偏移 + case 6: { // 直流偏移 QSpinBox* spinbox = new QSpinBox(parent); spinbox->setRange(-1000, 1000); editor = spinbox; } break; - case 6: { // 上升时间 + case 7: { // 成形时间 QSpinBox* spinbox = new QSpinBox(parent); - spinbox->setRange(1, 255); + spinbox->setRange(1, 10); editor = spinbox; } break; - case 7: { // 平顶时间 - QSpinBox* spinbox = new QSpinBox(parent); - spinbox->setRange(1, 255); + case 8: { // 快通道触发阈值 + QDoubleSpinBox* spinbox = new QDoubleSpinBox(parent); + spinbox->setRange(0, 1000); editor = spinbox; } break; - case 8: { // 最大能量范围 - QSpinBox* spinbox = new QSpinBox(parent); - spinbox->setRange(0, 99999); - editor = spinbox; + case 9: { // CR微分模式 + QComboBox *combobox = new QComboBox(parent); + combobox->addItem(QStringLiteral(u"启用"), true); + combobox->addItem(QStringLiteral(u"禁用"), false); + editor = combobox; + } break; + case 10: { // 输入信号正负极性选择 + QComboBox *combobox = new QComboBox(parent); + combobox->addItem(QStringLiteral(u"启用"), true); + combobox->addItem(QStringLiteral(u"禁用"), false); + editor = combobox; } break; default: break; @@ -80,24 +105,47 @@ void DeviceParamsItemDelegate::setEditorData(QWidget* editor, const QModelIndex& int col = index.column(); switch (col) { case 1: - case 2: { + case 2: + case 3: { QComboBox *combo = qobject_cast(editor); if (combo) { int idx = combo->findText(value.toString()); if (idx >= 0) combo->setCurrentIndex(idx); } } break; - case 3: - case 4: - case 5: - case 6: - case 7: - case 8: { + case 4: { QSpinBox *spinbox = qobject_cast(editor); if (spinbox) { spinbox->setValue(value.toUInt()); } } break; + case 5: { + QDoubleSpinBox *spinbox = qobject_cast(editor); + if (spinbox) { + spinbox->setValue(value.toDouble()); + } + } break; + case 6: + case 7: { + QSpinBox *spinbox = qobject_cast(editor); + if (spinbox) { + spinbox->setValue(value.toUInt()); + } + } break; + case 8: { + QDoubleSpinBox *spinbox = qobject_cast(editor); + if (spinbox) { + spinbox->setValue(value.toDouble()); + } + } break; + case 9: + case 10: { + QComboBox *combo = qobject_cast(editor); + if (combo) { + int idx = combo->findText(value.toString()); + if (idx >= 0) combo->setCurrentIndex(idx); + } + } break; default: break; } @@ -108,23 +156,45 @@ void DeviceParamsItemDelegate::setModelData(QWidget* editor, QAbstractItemModel* int col = index.column(); switch (col) { case 1: - case 2: { + case 2: + case 3: { QComboBox *combobox = qobject_cast(editor); if (combobox) { model->setData(index, combobox->currentText()); } } break; - case 3: - case 4: - case 5: - case 6: - case 7: - case 8: { + case 4: { QSpinBox *spinbox = qobject_cast(editor); if (spinbox) { model->setData(index, spinbox->value()); } } break; + case 5: { + QDoubleSpinBox *spinbox = qobject_cast(editor); + if (spinbox) { + model->setData(index, spinbox->value()); + } + } break; + case 6: + case 7: { + QSpinBox *spinbox = qobject_cast(editor); + if (spinbox) { + model->setData(index, spinbox->value()); + } + } break; + case 8: { + QDoubleSpinBox *spinbox = qobject_cast(editor); + if (spinbox) { + model->setData(index, spinbox->value()); + } + } break; + case 9: + case 10: { + QComboBox *combobox = qobject_cast(editor); + if (combobox) { + model->setData(index, combobox->currentText()); + } + } break; default: break; } @@ -171,6 +241,7 @@ DeviceParamsTableForm::DeviceParamsTableForm(QWidget* parent) ui->params_cfg_table->setItem(row, 7, new QTableWidgetItem()); ui->params_cfg_table->setItem(row, 8, new QTableWidgetItem()); ui->params_cfg_table->setItem(row, 9, new QTableWidgetItem()); + ui->params_cfg_table->setItem(row, 10, new QTableWidgetItem()); } connect(ui->btn_all_select, &QPushButton::clicked, this, &DeviceParamsTableForm::onAllSelectBtnClicked); @@ -178,6 +249,7 @@ DeviceParamsTableForm::DeviceParamsTableForm(QWidget* parent) connect(ui->btn_channel_select, &QPushButton::clicked, this, &DeviceParamsTableForm::onCfgChannelSelectBtnClicked); connect(ui->btn_update_to_other, &QPushButton::clicked, this, &DeviceParamsTableForm::onCurrentChannelToOther); connect(ui->btn_save, &QPushButton::clicked, this, &DeviceParamsTableForm::onSaveSelectedChannelConfig); + connect(ui->btn_save_to_sys, &QPushButton::clicked, this, &DeviceParamsTableForm::onSaveSelectedChannelConfigToSys); } DeviceParamsTableForm::~DeviceParamsTableForm() @@ -204,6 +276,18 @@ void DeviceParamsTableForm::SetConfigFilename(const QString& filename) if (!json_doc.isObject()) return; QVariantMap device_config_info = json_doc.object().toVariantMap(); + if (device_config_info.contains(QStringLiteral(u"ParamsConfigureInfo"))) { + QVariantMap config_info = device_config_info[QStringLiteral(u"ParamsConfigureInfo")].toMap(); + if (config_info.contains(QStringLiteral(u"Name"))) { + this->_cfg_name = config_info[QStringLiteral(u"Name")].toString(); + } + if (config_info.contains(QStringLiteral(u"Description"))) { + this->_cfg_description = config_info[QStringLiteral(u"Description")].toString(); + } + } + + this->ClearParamsTable(); + if (!device_config_info.contains(QStringLiteral(u"ChannelConfig"))) return; QVariantList channel_config_list = device_config_info[QStringLiteral(u"ChannelConfig")].toList(); @@ -220,31 +304,57 @@ void DeviceParamsTableForm::SetConfigFilename(const QString& filename) int row = board_id * 4 + channel_id; if (row >= 32) continue; - QVariantMap channel_info; - channel_info["board_id"] = board_id; - channel_info["channel_id"] = channel_id; - ui->params_cfg_table->item(row, 0)->setData(Qt::UserRole, channel_info); + // QVariantMap channel_info; + // channel_info["board_id"] = board_id; + // channel_info["channel_id"] = channel_id; + // ui->params_cfg_table->item(row, 0)->setData(Qt::UserRole, channel_info); if (channel_config_info.contains("AddrCount")) ui->params_cfg_table->item(row, 1)->setText(channel_config_info["AddrCount"].toString()); + if (channel_config_info.contains("TransferMode")) { + int transfer_mode = channel_config_info["TransferMode"].toInt(); + ui->params_cfg_table->item(row, 2)->setText(s_transfer_mode_list.value(transfer_mode)); + } if (channel_config_info.contains("DeviceGain")) - ui->params_cfg_table->item(row, 2)->setText(channel_config_info["DeviceGain"].toString()); - if (channel_config_info.contains("DeviceGainSelectIndex")) - ui->params_cfg_table->item(row, 2)->setData(Qt::UserRole, channel_config_info["DeviceGainSelectIndex"]); + ui->params_cfg_table->item(row, 3)->setText(channel_config_info["DeviceGain"].toString()); + // if (channel_config_info.contains("DeviceGainSelectIndex")) + // ui->params_cfg_table->item(row, 3)->setData(Qt::UserRole, channel_config_info["DeviceGainSelectIndex"]); if (channel_config_info.contains("SoftGain")) - ui->params_cfg_table->item(row, 3)->setText(channel_config_info["SoftGain"].toString()); + ui->params_cfg_table->item(row, 4)->setText(channel_config_info["SoftGain"].toString()); if (channel_config_info.contains("TimeConst")) - ui->params_cfg_table->item(row, 4)->setText(channel_config_info["TimeConst"].toString()); + ui->params_cfg_table->item(row, 5)->setText(channel_config_info["TimeConst"].toString()); if (channel_config_info.contains("DcOffset")) - ui->params_cfg_table->item(row, 5)->setText(channel_config_info["DcOffset"].toString()); - if (channel_config_info.contains("RiseTime")) - ui->params_cfg_table->item(row, 6)->setText(channel_config_info["RiseTime"].toString()); - if (channel_config_info.contains("FlatTime")) - ui->params_cfg_table->item(row, 7)->setText(channel_config_info["FlatTime"].toString()); - if (channel_config_info.contains("MaxEnergy")) - ui->params_cfg_table->item(row, 8)->setText(channel_config_info["MaxEnergy"].toString()); + ui->params_cfg_table->item(row, 6)->setText(channel_config_info["DcOffset"].toString()); + if (channel_config_info.contains("FormTime")) + ui->params_cfg_table->item(row, 7)->setText(channel_config_info["FormTime"].toString()); + if (channel_config_info.contains("FastChannelTrigerValue")) + ui->params_cfg_table->item(row, 8)->setText(channel_config_info["FastChannelTrigerValue"].toString()); + if (channel_config_info.contains("CRDivMode")) { + bool CRDiv_mode = channel_config_info["CRDivMode"].toBool(); + ui->params_cfg_table->item(row, 9)->setText(CRDiv_mode ? QStringLiteral(u"启用") : QStringLiteral(u"禁用")); + } + if (channel_config_info.contains("InputSignalPostive")) { + bool input_signal_postive = channel_config_info["InputSignalPostive"].toBool(); + ui->params_cfg_table->item(row, 10)->setText(input_signal_postive ? QStringLiteral(u"启用") : QStringLiteral(u"禁用")); + } } } +void DeviceParamsTableForm::SetButtonEnable(bool enable) +{ + ui->btn_save->setVisible(enable); + ui->btn_save_to_sys->setVisible(enable); +} + +const QString &DeviceParamsTableForm::GetConfigName() const +{ + return _cfg_name; +} + +const QString &DeviceParamsTableForm::GetConfigDescription() const +{ + return _cfg_description; +} + void DeviceParamsTableForm::onAllSelectBtnClicked() { for (int row = 0; row < 32; ++row) { @@ -322,14 +432,57 @@ void DeviceParamsTableForm::onCurrentChannelToOther() for (int row = 0; row < 32; ++row) { if (ui->params_cfg_table->isRowHidden(row)) continue; - for (int col = 1; col < ui->params_cfg_table->columnCount(); ++col) { - const QString& current_value = ui->params_cfg_table->item(current_row, col)->text(); - ui->params_cfg_table->item(row, col)->setText(current_value); + if (ui->params_cfg_table->item(row, 0)->checkState() == Qt::Checked) { + for (int col = 1; col < ui->params_cfg_table->columnCount(); ++col) { + QTableWidgetItem* current_item = ui->params_cfg_table->item(current_row, col); + if (current_item) { + const QString& current_value = current_item->text(); + ui->params_cfg_table->item(row, col)->setText(current_value); + } + } } } } void DeviceParamsTableForm::onSaveSelectedChannelConfig() +{ + if (SaveSelectedChannelConfig(this->_config_filename, this->_cfg_name, this->_cfg_description)) { + emit deviceConfigParamsSaved(this->_config_filename); + } +} + +void DeviceParamsTableForm::onSaveSelectedChannelConfigToSys() +{ + int selected_channel_count = 0; + for (int row = 0; row < 32; ++row) { + if (ui->params_cfg_table->item(row, 0)->checkState() == Qt::Checked) { + ++selected_channel_count; + } + } + if (0 == selected_channel_count) { + QMessageBox::information(this, QStringLiteral(u"提示"), QStringLiteral(u"请选择需要保存的测量设备通道配置参数!")); + return; + } + DeviceParamsSaveToSysDlg params_save_to_sys_dlg; + if (QDialog::Accepted == params_save_to_sys_dlg.exec()) { + const QString& device_params_dir_path = QDir(qApp->applicationDirPath()).filePath("configure/DeviceParams"); + const QString params_cfg_name = params_save_to_sys_dlg.GetCfgName(); + const QString params_cfg_description = params_save_to_sys_dlg.GetCfgDescription(); + const QString params_cfg_filename = QDir(device_params_dir_path).filePath(params_cfg_name) + ".mscfg"; + if (QFile::exists(params_cfg_filename)) { + QMessageBox::warning(this, QStringLiteral(u"警告"), QStringLiteral(u"设备测量参数配置\"%1\"已存在!").arg(params_cfg_name)); + } else { + if (this->SaveSelectedChannelConfig(params_cfg_filename, params_cfg_name, params_cfg_description)) { + this->_cfg_name = params_cfg_name; + this->_cfg_description = params_cfg_description; + QMessageBox::information(this, QStringLiteral(u"提示"), QStringLiteral(u"保存设备测量参数配置\"%1\"完成").arg(params_cfg_name)); + } + } + + } +} + +bool DeviceParamsTableForm::SaveSelectedChannelConfig(const QString &save_filename, const QString& cfg_name, const QString& description) { QVariantList device_channel_params_list; for (int row = 0; row < 32; ++row) { @@ -338,44 +491,82 @@ void DeviceParamsTableForm::onSaveSelectedChannelConfig() int board_id = channel_info["board_id"].toInt(); int channel_id = channel_info["channel_id"].toInt(); int addr_count = ui->params_cfg_table->item(row, 1)->text().toInt(); - int device_gain = ui->params_cfg_table->item(row, 2)->text().toInt(); - int device_gain_index = ui->params_cfg_table->item(row, 2)->data(Qt::UserRole).toInt(); - uint soft_gain = ui->params_cfg_table->item(row, 3)->text().toUInt(); - int time_const = ui->params_cfg_table->item(row, 4)->text().toInt(); - int dc_offset = ui->params_cfg_table->item(row, 5)->text().toInt(); - int rise_time = ui->params_cfg_table->item(row, 6)->text().toInt(); - int flat_time = ui->params_cfg_table->item(row, 7)->text().toInt(); - int max_energy = ui->params_cfg_table->item(row, 8)->text().toInt(); - + auto transfer_mode_value = [](const QString& transfer_mode_text) { + int transfer_mode = 3; + for (QMap::iterator it = s_transfer_mode_list.begin(); it != s_transfer_mode_list.end(); ++it) { + if (it.value() == transfer_mode_text) { + transfer_mode = it.key(); + break; + } + } + return transfer_mode; + }; + int transfer_mode = transfer_mode_value(ui->params_cfg_table->item(row, 2)->text()); + int device_gain = ui->params_cfg_table->item(row, 3)->text().toInt(); + int device_gain_index = s_device_gain_list.indexOf(ui->params_cfg_table->item(row, 3)->text()) + 1; + uint soft_gain = ui->params_cfg_table->item(row, 4)->text().toUInt(); + double time_const = ui->params_cfg_table->item(row, 5)->text().toDouble(); + int dc_offset = ui->params_cfg_table->item(row, 6)->text().toInt(); + int form_time = ui->params_cfg_table->item(row, 7)->text().toInt(); + double fast_channel_triger_value = ui->params_cfg_table->item(row, 8)->text().toDouble(); + + auto is_enable = [](const QString& text) { + bool enable = false; + if (QStringLiteral(u"启用") == text) { + enable = true; + } else if (QStringLiteral(u"禁用") == text) { + enable = false; + } + return enable; + }; + bool CRDiv_mode = is_enable(ui->params_cfg_table->item(row, 9)->text()); + bool input_signal_postive = is_enable(ui->params_cfg_table->item(row, 10)->text()); + QVariantMap device_channel_params; device_channel_params["BoardId"] = board_id; device_channel_params["ChannelId"] = channel_id; device_channel_params["AddrCount"] = addr_count; + device_channel_params["TransferMode"] = transfer_mode; device_channel_params["DeviceGain"] = device_gain; device_channel_params["DeviceGainSelectIndex"] = device_gain_index; device_channel_params["SoftGain"] = soft_gain; device_channel_params["TimeConst"] = time_const; device_channel_params["DcOffset"] = dc_offset; - device_channel_params["RiseTime"] = rise_time; - device_channel_params["FlatTime"] = flat_time; - device_channel_params["MaxEnergy"] = max_energy; + device_channel_params["FormTime"] = form_time; + device_channel_params["FastChannelTrigerValue"] = fast_channel_triger_value; + device_channel_params["CRDivMode"] = CRDiv_mode; + device_channel_params["InputSignalPostive"] = input_signal_postive; device_channel_params_list.append(device_channel_params); } } - if (device_channel_params_list.isEmpty()) { - QMessageBox::information(this, QStringLiteral(u"提示"), QStringLiteral(u"请选择需要保存的测量设备通道配置参数!")); - return; - } + // if (device_channel_params_list.isEmpty()) { + // QMessageBox::information(this, QStringLiteral(u"提示"), QStringLiteral(u"请选择需要保存的测量设备通道配置参数!")); + // return false; + // } QVariantMap device_config_info; + if (!cfg_name.isEmpty()) { + QVariantMap cfg_info; + cfg_info["Name"] = cfg_name; + cfg_info["Description"] = description; + device_config_info["ParamsConfigureInfo"] = cfg_info; + } device_config_info["ChannelConfig"] = device_channel_params_list; QJsonDocument json_doc = QJsonDocument::fromVariant(device_config_info); - QFile json_file(this->_config_filename); + QFile json_file(save_filename); if (!json_file.open(QIODevice::WriteOnly | QIODevice::Text)) { - return; + return false; } json_file.write(json_doc.toJson()); json_file.close(); - LOG_INFO(QStringLiteral(u"测量设备参数配置保存完成.")); - - emit deviceConfigParamsSaved(this->_config_filename); + LOG_INFO(QStringLiteral(u"测量设备参数配置保存完成: %1.").arg(save_filename)); + return true; +} + +void DeviceParamsTableForm::ClearParamsTable() +{ + for (int row = 0; row < ui->params_cfg_table->rowCount(); ++row) { + for (int col = 1; col < ui->params_cfg_table->columnCount(); ++col) { + ui->params_cfg_table->item(row, col)->setText(QString()); + } + } } diff --git a/src/MeasureDeviceParamsConfigView/DeviceParamsTableForm.h b/src/MeasureDeviceParamsConfigView/DeviceParamsTableForm.h index ee03eaf..635325a 100644 --- a/src/MeasureDeviceParamsConfigView/DeviceParamsTableForm.h +++ b/src/MeasureDeviceParamsConfigView/DeviceParamsTableForm.h @@ -15,11 +15,8 @@ public: explicit DeviceParamsItemDelegate(QObject *parent = nullptr); QWidget* createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override; - void setEditorData(QWidget *editor, const QModelIndex &index) const override; - void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override; - void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const override; protected: @@ -36,12 +33,20 @@ public: void SetConfigFilename(const QString& filename); + void SetButtonEnable(bool enable = true); + const QString& GetConfigName() const; + const QString& GetConfigDescription() const; + + void ClearParamsTable(); + bool SaveSelectedChannelConfig(const QString& save_filename, const QString &cfg_name = QString(), const QString &description = QString()); + private slots: void onAllSelectBtnClicked(); void onReserveSelectBtnClicked(); void onCfgChannelSelectBtnClicked(); void onCurrentChannelToOther(); void onSaveSelectedChannelConfig(); + void onSaveSelectedChannelConfigToSys(); signals: void deviceConfigParamsSaved(const QString& filename); @@ -49,6 +54,8 @@ signals: private: Ui::DeviceParamsTableForm *ui; QString _config_filename; + QString _cfg_name; + QString _cfg_description; }; #endif // DEVICEPARAMSTABLEFORM_H diff --git a/src/MeasureDeviceParamsConfigView/DeviceParamsTableForm.ui b/src/MeasureDeviceParamsConfigView/DeviceParamsTableForm.ui index 34d8935..62f1c9b 100644 --- a/src/MeasureDeviceParamsConfigView/DeviceParamsTableForm.ui +++ b/src/MeasureDeviceParamsConfigView/DeviceParamsTableForm.ui @@ -42,7 +42,7 @@ - 应用当前通道配置到其他通道 + 应用当前通道配置到选择通道 @@ -68,6 +68,13 @@ + + + + 保存到系统 + + + @@ -88,6 +95,11 @@ 道址数 + + + 数据模式 + + 硬件增益 @@ -110,17 +122,22 @@ - 上升时间 + 成形时间 - 平顶时间 + 快通道触发阈值 - 最大能量范围 + CR微分模式 + + + + + 输入信号正负极性选择 diff --git a/src/ThreeDimensionalConformityAnalysisView/CoincidenceSpectrumProcess.h b/src/ThreeDimensionalConformityAnalysisView/CoincidenceSpectrumProcess.h deleted file mode 100644 index be85b64..0000000 --- a/src/ThreeDimensionalConformityAnalysisView/CoincidenceSpectrumProcess.h +++ /dev/null @@ -1,75 +0,0 @@ -#ifndef COINCIDENCESPECTRUMPROCESS_H -#define COINCIDENCESPECTRUMPROCESS_H - -#include -// 定义板卡和通道的最大数量 -static constexpr int MAX_BOARD = 8; -static constexpr int MAX_CHANNEL = 4; - -// 用于存储三维数据 -typedef struct SurfacePoint { - float primaryEnergy; // 初级粒子能量 - float secondaryEnergySum; // 次级粒子能量和 - int count; // 符合事件计数 -}SURFACEPOINT; - - - - -namespace CoincidenceSpectrum { - -// 二次符合事件筛选 -arma::mat EventFilter2Order(const arma::mat& raw_spec_data, double conformity_event_time_win = 50.0f); - -// 计算二维直方图 -void Hist3(const arma::mat& data, int nx, int ny, arma::mat& counts, arma::vec& x_edges, arma::vec& y_edges); - -// 二次符合事件处理 -namespace F2t9Order { - - // 能谱数据结构 - struct SpectrumData { - int board_id; // 板卡号 - int channel_id; // 通道号 - double energy; // 能量 - unsigned long long timestamp; // 时间戳(纳秒) - }; - - // 符合事件结果结构 - struct CoincidenceEvent { - int coincidence_order; // 符合次数(2-9) - std::vector events; // 符合的事件集合 - unsigned int time_window; // 使用的时间窗口(秒) - }; - - // 读取CSV数据文件 - std::vector ReadCsv(const std::string& filename); - - // 按时间戳排序数据 - void SortDataByTimestamp(std::vector& data); - - // 2-9次能谱符合处理 - std::vector ProcessCoincidence( - const std::vector& data, - unsigned int time_window, // 时间窗口(纳秒) - int min_order = 2, // 最小符合次数 - int max_order = 9 // 最大符合次数 - ); - - // 统计符合事件结果 - arma::mat AnalyzeCoincidenceResults( - const std::vector& results, - int max_order = 9 - ); - - // 保存结果到文件 - void SaveResults( - const std::vector& results, - const arma::mat& stats, - const std::string& base_filename = "coincidence_results" - ); -}; - -} - -#endif // COINCIDENCESPECTRUMPROCESS_H diff --git a/src/main.cpp b/src/main.cpp index f391c5c..6d672cd 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -7,6 +7,17 @@ #include "QsLogManage.h" #include +void InitAppRunEnv() { + // 在应用程序可执行文件所在目录检查并创建Projects目录 + QString projects_dir_path = QDir(qApp->applicationDirPath()).filePath("Projects"); + QDir projects_dir(projects_dir_path); + projects_dir.mkpath(projects_dir_path); + + QString device_params_dir_path = QDir(qApp->applicationDirPath()).filePath("configure/DeviceParams"); + QDir device_params_dir(device_params_dir_path); + device_params_dir.mkpath(device_params_dir_path); +} + int main(int argc, char *argv[]) { qputenv("QT_WIN_DEBUG_CONSOLE", "attach"); @@ -53,12 +64,7 @@ int main(int argc, char *argv[]) app.setWindowIcon(QIcon(":/logo/256.png")); app.setQuitOnLastWindowClosed(true); - // 在应用程序可执行文件所在目录检查并创建Projects目录 - QString projects_dir_path = QDir(app.applicationDirPath()).filePath("Projects"); - QDir projects_dir(projects_dir_path); - if (!projects_dir.exists()) { - projects_dir.mkpath(projects_dir_path); - } + InitAppRunEnv(); MainWindow w; w.showMaximized(); diff --git a/src/src.pro b/src/src.pro index 44f3290..1509c70 100644 --- a/src/src.pro +++ b/src/src.pro @@ -8,7 +8,6 @@ msvc { QMAKE_CXXFLAGS += /utf-8 } - include($${PWD}/../Common.pri) include($${PROJECT_DIR}/3rdlib/QsLog/QsLog.pri) include($${PROJECT_DIR}/3rdlib/QtAdvancedDockingSystem/ads.pri) @@ -38,8 +37,8 @@ INCLUDEPATH += \ $${PWD}/DeviceParameterConfig \ $${PWD}/2DSpectralCompliance \ $${PWD}/ConformToTheEnergySpectrum \ - $${PWD}/NuclideLib - + $${PWD}/NuclideLib \ + $${PWD}/AntiConformEnergySpectrumView DEPENDPATH += \ $${PWD}/BusyIndicator \ @@ -57,11 +56,8 @@ DEPENDPATH += \ $${PWD}/DeviceParameterConfig \ $${PWD}/2DSpectralCompliance \ $${PWD}/ConformToTheEnergySpectrum \ - $${PWD}/NuclideLib - - - - + $${PWD}/NuclideLib \ + $${PWD}/AntiConformEnergySpectrumView SOURCES += \ 2DSpectralCompliance/TwoDSpectralCompliance.cpp \ @@ -70,9 +66,6 @@ SOURCES += \ CountRateAnalysisView/CountRateAnalysisView.cpp \ CustomQwtPlot.cpp \ DataProcessWorkPool.cpp \ - DeviceParameterConfig/DeviceConfigView.cpp \ - DeviceParameterConfig/DeviceParameterConfig.cpp \ - DeviceParameterConfig/DeviceParameterConfigList.cpp \ EnergyCountPeakFitView/EnergyCountPeakFitView.cpp \ EnergyCountPeakFitView/PeakFitParamsDialog.cpp \ EnergyCountPeakFitView/PlotRectItem.cpp \ @@ -82,6 +75,8 @@ SOURCES += \ MainWindow.cpp \ MeasureAnalysisDataTableView/MeasureAnalysisDataTableView.cpp \ MeasureAnalysisHistoryForm/MeasureAnalysisHistoryForm.cpp \ + MeasureDeviceParamsConfigView/DeviceParamsManagerDlg.cpp \ + MeasureDeviceParamsConfigView/DeviceParamsSaveToSysDlg.cpp \ MeasureDeviceParamsConfigView/DeviceParamsTableForm.cpp \ MeasureDeviceParamsConfigView/MeasureDeviceParamsConfigView.cpp \ NuclideLib/NuclideEditDialog.cpp \ @@ -93,7 +88,6 @@ SOURCES += \ ParticleCountPlotView/ParticleCountPlotView.cpp \ MeasureAnalysisTreeView.cpp \ MeasureAnalysisView.cpp \ - MeasureDeviceParamsCfgForm.cpp \ NewMeasureAnalysisDlg.cpp \ MeasureAnalysisProjectModel.cpp \ ParticleInjectTimeView/ParticleInjectTimeAnalysisView.cpp \ @@ -107,9 +101,9 @@ SOURCES += \ ThreeDimensionalConformityAnalysisView/ParticleDataStatistics.cpp \ ThreeDimensionalConformityAnalysisView/ThreeDDisplay.cpp \ EnergyCountPeakFitView/EnergyCountPeakFitView.cpp \ - DeviceParameterConfig/DeviceParameterProxy.cpp \ ConformToTheEnergySpectrum/ConformToTheEnergySpectrum.cpp \ NuclideLib/NuclideLib.cpp \ + AntiConformEnergySpectrumView/AntiConformEnergySpectrumView.cpp \ main.cpp HEADERS += \ @@ -120,9 +114,6 @@ HEADERS += \ CountRateAnalysisView/CountRateAnalysisView.h \ CustomQwtPlot.h \ DataProcessWorkPool.h \ - DeviceParameterConfig/DeviceConfigView.h \ - DeviceParameterConfig/DeviceParameterConfig.h \ - DeviceParameterConfig/DeviceParameterConfigList.h \ EnergyCountPeakFitView/EnergyCountPeakFitView.h \ EnergyCountPeakFitView/PeakFitParamsDialog.h \ EnergyCountPeakFitView/PlotRectItem.h \ @@ -133,6 +124,8 @@ HEADERS += \ MainWindow.h \ MeasureAnalysisDataTableView/MeasureAnalysisDataTableView.h \ MeasureAnalysisHistoryForm/MeasureAnalysisHistoryForm.h \ + MeasureDeviceParamsConfigView/DeviceParamsManagerDlg.h \ + MeasureDeviceParamsConfigView/DeviceParamsSaveToSysDlg.h \ MeasureDeviceParamsConfigView/DeviceParamsTableForm.h \ MeasureDeviceParamsConfigView/MeasureDeviceParamsConfigView.h \ NuclideLib/NuclideEditDialog.h \ @@ -144,7 +137,6 @@ HEADERS += \ ParticleCountPlotView/ParticleCountPlotView.h \ MeasureAnalysisTreeView.h \ MeasureAnalysisView.h \ - MeasureDeviceParamsCfgForm.h \ NewMeasureAnalysisDlg.h \ MeasureAnalysisProjectModel.h \ ParticleInjectTimeView/ParticleInjectTimeAnalysisView.h \ @@ -159,12 +151,9 @@ HEADERS += \ ThreeDimensionalConformityAnalysisView/ParticleDataStatistics.h \ ThreeDimensionalConformityAnalysisView/ThreeDDisplay.h \ EnergyCountPeakFitView/EnergyCountPeakFitView.h \ - DeviceParameterConfig/DeviceParameterProxy.h \ ConformToTheEnergySpectrum/ConformToTheEnergySpectrum.h \ - NuclideLib/NuclideLib.h - - - + NuclideLib/NuclideLib.h \ + AntiConformEnergySpectrumView/AntiConformEnergySpectrumView.h FORMS += \ 2DSpectralCompliance/TwoDSpectralCompliance.ui \ @@ -173,9 +162,10 @@ FORMS += \ EnergyScaleForm.ui \ MainWindow.ui \ MeasureAnalysisHistoryForm/MeasureAnalysisHistoryForm.ui \ + MeasureDeviceParamsConfigView/DeviceParamsManagerDlg.ui \ + MeasureDeviceParamsConfigView/DeviceParamsSaveToSysDlg.ui \ MeasureDeviceParamsConfigView/DeviceParamsTableForm.ui \ ParticleCountPlotView/BatchEnergyScaleDialog.ui \ - MeasureDeviceParamsCfgForm.ui \ NewMeasureAnalysisDlg.ui \ ThreeDimensionalConformityAnalysisView/DetectorStatusSummary.ui \ ThreeDimensionalConformityAnalysisView/ParticleDataStatistics.ui \ @@ -183,7 +173,6 @@ FORMS += \ ThreeDimensionalConformityAnalysisView/ConformityAnalysis.ui \ NuclideLib/NuclideLib.ui - DEFINES += ENABLE_DEBUG contains(DEFINES, ENABLE_DEBUG) { CONFIG += console diff --git a/style/stylesheet/default.qss b/style/stylesheet/default.qss index 1a1766c..c302a86 100644 --- a/style/stylesheet/default.qss +++ b/style/stylesheet/default.qss @@ -48,7 +48,7 @@ QHeaderView::section { font-weight: normal; } - +/* QScrollBar { background-color: #f6f5ec; padding: 0px; @@ -90,5 +90,5 @@ QScrollBar::add-page { QScrollBar::sub-page { background: rgba(0, 0, 0, 0); } - +*/