diff --git a/src/2DSpectralCompliance/TwoDSpectralCompliance.cpp b/src/2DSpectralCompliance/TwoDSpectralCompliance.cpp index 5c97464..faa0c2f 100644 --- a/src/2DSpectralCompliance/TwoDSpectralCompliance.cpp +++ b/src/2DSpectralCompliance/TwoDSpectralCompliance.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -15,16 +16,21 @@ #include #include #include - -// 自定义颜色映射(热力图) +#include +#include +#include +#include +#include +#include class HeatMapColorMap : public QwtLinearColorMap { public: - HeatMapColorMap() : QwtLinearColorMap(Qt::white, Qt::red) + HeatMapColorMap() : QwtLinearColorMap(Qt::blue, Qt::red) { - addColorStop(0.25, Qt::blue); + addColorStop(0.25, Qt::cyan); addColorStop(0.5, Qt::green); addColorStop(0.75, Qt::yellow); + addColorStop(0.90, Qt::darkRed); } }; @@ -38,6 +44,7 @@ TwoDSpectralCompliance::TwoDSpectralCompliance(QWidget *parent) : this->_plot = new CustomQwtPlot(this); layout->addWidget(this->_plot); setupPlot(); + createFloatingInfoWidget(); } TwoDSpectralCompliance::~TwoDSpectralCompliance() @@ -47,7 +54,6 @@ TwoDSpectralCompliance::~TwoDSpectralCompliance() void TwoDSpectralCompliance::InitViewWorkspace(const QString &project_name) { - // 可预留用于项目初始化 Q_UNUSED(project_name); } @@ -55,9 +61,6 @@ void TwoDSpectralCompliance::SetAnalyzeDataFilename(const QMapsetCanvasBackground(Qt::white); @@ -76,38 +80,29 @@ void TwoDSpectralCompliance::setupPlot() QFont font = this->font(); font.setBold(false); - QwtText energy_label = QStringLiteral(u"次级粒子能量和 (keV)"); + QwtText energy_label = QStringLiteral(u"初级粒子能量"); energy_label.setFont(font); - QwtText count_label = QStringLiteral(u"初级粒子能量 (keV)"); + QwtText count_label = QStringLiteral(u"次级粒子能量"); count_label.setFont(font); _plot->setAxisTitle(QwtPlot::xBottom, energy_label); _plot->setAxisTitle(QwtPlot::yLeft, count_label); - // 自动缩放 _plot->setAxisAutoScale(QwtPlot::xBottom, true); _plot->setAxisAutoScale(QwtPlot::yLeft, true); _plot->enableAxis(QwtPlot::xBottom); _plot->enableAxis(QwtPlot::yLeft); - // 图例 QwtLegend* legend = new QwtLegend(); legend->setDefaultItemMode(QwtLegendData::ReadOnly); _plot->insertLegend(legend, QwtPlot::RightLegend); - // 启用拖拽缩放 _plot->SetAxisDragScale(QwtPlot::xBottom, true); _plot->SetAxisDragScale(QwtPlot::yLeft, true); - // 创建 spectrogram _spectrogram = new QwtPlotSpectrogram(); _spectrogram->setColorMap(new HeatMapColorMap()); _spectrogram->attach(_plot); - - _plot->setAutoFillBackground(true); - QPalette pal = _plot->palette(); - pal.setColor(QPalette::Window, Qt::white); - _plot->setPalette(pal); } void TwoDSpectralCompliance::readCsv(const QString &filename) @@ -115,12 +110,12 @@ void TwoDSpectralCompliance::readCsv(const QString &filename) m_rawData.clear(); QFile file(filename); if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { - qWarning() << "无法打开文件:" << filename; + qWarning() << QStringLiteral(u"无法打开文件:") << filename; return; } QTextStream stream(&file); - QString header = stream.readLine(); // 跳过标题行 + QString header = stream.readLine(); Q_UNUSED(header); while (!stream.atEnd()) { @@ -141,7 +136,6 @@ void TwoDSpectralCompliance::readCsv(const QString &filename) m_rawData.append(data); } file.close(); - qDebug() << "读取了" << m_rawData.size() << "条事件记录"; } void TwoDSpectralCompliance::generateSurfaceData() @@ -150,13 +144,11 @@ void TwoDSpectralCompliance::generateSurfaceData() if (m_rawData.isEmpty()) return; - // 按事件ID分组,每个事件中第一个粒子为初级,其余为次级 QMap> eventMap; for (const auto& ev : m_rawData) { eventMap[ev.eventId].append(ev); } - // 使用 QMap 来累加相同坐标的计数(初级能量,次级能量和) QMap, int> countMap; for (auto it = eventMap.begin(); it != eventMap.end(); ++it) { @@ -164,7 +156,6 @@ void TwoDSpectralCompliance::generateSurfaceData() if (events.isEmpty()) continue; - // 第一个事件作为初级粒子 float primaryEnergy = events[0].energy; float secondarySum = 0.0f; for (int i = 1; i < events.size(); ++i) { @@ -175,7 +166,6 @@ void TwoDSpectralCompliance::generateSurfaceData() countMap[key]++; } - // 转换为 SurfacePoint 列表 for (auto it = countMap.begin(); it != countMap.end(); ++it) { TwoSurfacePoint point; point.primaryEnergy = it.key().first; @@ -184,7 +174,6 @@ void TwoDSpectralCompliance::generateSurfaceData() m_surfaceData.append(point); } - qDebug() << "生成了" << m_surfaceData.size() << "个唯一坐标点"; } void TwoDSpectralCompliance::updateSpectrogram() @@ -195,7 +184,6 @@ void TwoDSpectralCompliance::updateSpectrogram() return; } - // 找出能量范围 float minPrim = 1e9f, maxPrim = -1e9f; float minSec = 1e9f, maxSec = -1e9f; int maxCount = 0; @@ -208,7 +196,6 @@ void TwoDSpectralCompliance::updateSpectrogram() maxCount = std::max(maxCount, pt.count); } - // 增加边界 double primRange = maxPrim - minPrim; double secRange = maxSec - minSec; if (primRange < 1e-6) primRange = 1.0; @@ -218,9 +205,8 @@ void TwoDSpectralCompliance::updateSpectrogram() double secStart = minSec - secRange * 0.05; double secEnd = maxSec + secRange * 0.05; - // 使用不同名称,避免宏冲突 - const int numCols = 200; // X轴方向点数(初级能量) - const int numRows = 200; // Y轴方向点数(次级能量) + const int numCols = 200; + const int numRows = 200; double stepX = (primEnd - primStart) / numCols; double stepY = (secEnd - secStart) / numRows; @@ -246,3 +232,203 @@ void TwoDSpectralCompliance::updateSpectrogram() _plot->setAxisScale(QwtPlot::yLeft, secStart, secEnd); _plot->replot(); } +void TwoDSpectralCompliance::createFloatingInfoWidget() +{ + // 悬浮窗口 + m_floatingWidget = new QWidget(this); + m_floatingWidget->setObjectName("FloatingInfoWidget"); + m_floatingWidget->setStyleSheet( + "QWidget#FloatingInfoWidget {" + " background-color: rgba(240, 240, 240, 240);" + " border: 1px solid gray;" + " border-radius: 5px;" + "}" + ); + m_floatingWidget->setFixedSize(320, 220); + m_floatingWidget->setAttribute(Qt::WA_TranslucentBackground, false); + + QVBoxLayout* mainLayout = new QVBoxLayout(m_floatingWidget); + mainLayout->setSpacing(5); + mainLayout->setContentsMargins(8, 8, 8, 8); + + // 标题栏(可拖动,并包含隐藏按钮) + QWidget* titleBar = new QWidget(); + QHBoxLayout* titleLayout = new QHBoxLayout(titleBar); + titleLayout->setContentsMargins(0, 0, 0, 0); + QLabel* titleLabel = new QLabel(QStringLiteral(u"数据统计信息")); + titleLabel->setStyleSheet("font-weight: bold;"); + titleLayout->addWidget(titleLabel); + titleLayout->addStretch(); + QPushButton* hideBtn = new QPushButton(QStringLiteral("−")); + hideBtn->setFixedSize(20, 20); + hideBtn->setToolTip(QStringLiteral(u"隐藏窗口")); + hideBtn->setStyleSheet("border: none; font-weight: bold;"); + titleLayout->addWidget(hideBtn); + mainLayout->addWidget(titleBar); + + QWidget* contentWidget = new QWidget(); + QFormLayout* formLayout = new QFormLayout(contentWidget); + formLayout->setSpacing(8); + formLayout->setLabelAlignment(Qt::AlignRight); + + m_totalEventsEdit = new QLineEdit; + m_totalEventsEdit->setReadOnly(true); + m_totalEventsEdit->setFixedWidth(130); + + m_totalPointsEdit = new QLineEdit; + m_totalPointsEdit->setReadOnly(true); + m_totalPointsEdit->setFixedWidth(130); + m_maxCountEdit = new QLineEdit; + m_maxCountEdit->setReadOnly(true); + m_maxCountEdit->setFixedWidth(130); + + m_primRangeEdit = new QLineEdit; + m_primRangeEdit->setReadOnly(true); + m_primRangeEdit->setFixedWidth(130); + + m_secRangeEdit = new QLineEdit; + m_secRangeEdit->setReadOnly(true); + m_secRangeEdit->setFixedWidth(130); + + formLayout->addRow(QStringLiteral(u"总事件数:"), m_totalEventsEdit); + formLayout->addRow(QStringLiteral(u"有效数据点:"), m_totalPointsEdit); + formLayout->addRow(QStringLiteral(u"最大计数:"), m_maxCountEdit); + formLayout->addRow(QStringLiteral(u"初级能量范围:"), m_primRangeEdit); + formLayout->addRow(QStringLiteral(u"次级能量和范围:"), m_secRangeEdit); + + mainLayout->addWidget(contentWidget); + mainLayout->addStretch(); + + connect(hideBtn, &QPushButton::clicked, this, &TwoDSpectralCompliance::hideFloatingWidget); + + titleBar->setCursor(Qt::SizeAllCursor); + m_floatingWidget->installEventFilter(this); + + m_showButton = new QPushButton(this); + m_showButton->setFixedSize(28, 28); + m_showButton->setToolTip(QStringLiteral(u"显示信息窗口")); + m_showButton->setStyleSheet( + "QPushButton {" + " background-color: rgba(200,200,200,200);" + " border: 1px solid #888;" + " border-radius: 14px;" + " font-weight: bold;" + "}" + "QPushButton:hover { background-color: rgba(150,150,150,200); }" + ); + m_showButton->setText("⊕"); + connect(m_showButton, &QPushButton::clicked, this, &TwoDSpectralCompliance::showFloatingWidget); + + m_floatingWidget->move(10, 10); + updateShowButtonPosition(); + m_floatingWidget->hide(); + m_showButton->show(); + +// m_floatingWidget->raise(); + updateInfoContent(); +} + +void TwoDSpectralCompliance::hideFloatingWidget() +{ + m_floatingWidget->hide(); + m_showButton->show(); + updateShowButtonPosition(); +} + +void TwoDSpectralCompliance::showFloatingWidget() +{ + m_floatingWidget->show(); + m_floatingWidget->raise(); + m_showButton->hide(); + updateInfoContent(); // 刷新内容 +} + +void TwoDSpectralCompliance::updateShowButtonPosition() +{ + if (m_showButton && m_showButton->isVisible()) { + m_showButton->move(10, 10); + } +} + +void TwoDSpectralCompliance::updateInfoContent() +{ + if (!m_totalEventsEdit) + return; + + if (m_surfaceData.isEmpty()) { + m_totalEventsEdit->setText(QStringLiteral(u"无数据")); + m_totalPointsEdit->setText(QStringLiteral(u"无数据")); + m_maxCountEdit->setText(QStringLiteral(u"无数据")); + m_primRangeEdit->setText(QStringLiteral(u"无数据")); + m_secRangeEdit->setText(QStringLiteral(u"无数据")); + return; + } + + int totalPoints = m_surfaceData.size(); + int maxCount = 0; + float minPrim = 1e9f, maxPrim = -1e9f; + float minSec = 1e9f, maxSec = -1e9f; + for (const auto& pt : m_surfaceData) { + minPrim = std::min(minPrim, pt.primaryEnergy); + maxPrim = std::max(maxPrim, pt.primaryEnergy); + minSec = std::min(minSec, pt.secondaryEnergySum); + maxSec = std::max(maxSec, pt.secondaryEnergySum); + maxCount = std::max(maxCount, pt.count); + } + + QSet eventIds; + for (const auto& ev : m_rawData) { + eventIds.insert(ev.eventId); + } + int totalEvents = eventIds.size(); + + m_totalEventsEdit->setText(QString::number(totalEvents)); + m_totalPointsEdit->setText(QString::number(totalPoints)); + m_maxCountEdit->setText(QString::number(maxCount)); + m_primRangeEdit->setText(QString("[%1, %2]").arg(minPrim, 0, 'f', 2).arg(maxPrim, 0, 'f', 2)); + m_secRangeEdit->setText(QString("[%1, %2]").arg(minSec, 0, 'f', 2).arg(maxSec, 0, 'f', 2)); +} + +void TwoDSpectralCompliance::resizeEvent(QResizeEvent *event) +{ + QWidget::resizeEvent(event); + updateShowButtonPosition(); + if (m_floatingWidget && m_floatingWidget->isVisible()) { + // 限制悬浮窗口不超出父窗口边界 + QRect rect = m_floatingWidget->geometry(); + int newX = qBound(0, rect.x(), width() - rect.width()); + int newY = qBound(0, rect.y(), height() - rect.height()); + if (newX != rect.x() || newY != rect.y()) + m_floatingWidget->move(newX, newY); + m_floatingWidget->raise(); + } +} + +bool TwoDSpectralCompliance::eventFilter(QObject *obj, QEvent *event) +{ + if (obj == m_floatingWidget) { + if (event->type() == QEvent::MouseButtonPress) { + QMouseEvent *mouseEvent = static_cast(event); + if (mouseEvent->button() == Qt::LeftButton) { + m_dragging = true; + m_dragPosition = mouseEvent->globalPos() - m_floatingWidget->frameGeometry().topLeft(); + event->accept(); + return true; + } + } else if (event->type() == QEvent::MouseMove) { + if (m_dragging) { + QMouseEvent *mouseEvent = static_cast(event); + m_floatingWidget->move(mouseEvent->globalPos() - m_dragPosition); + event->accept(); + return true; + } + } else if (event->type() == QEvent::MouseButtonRelease) { + if (m_dragging) { + m_dragging = false; + event->accept(); + return true; + } + } + } + return QWidget::eventFilter(obj, event); +} diff --git a/src/2DSpectralCompliance/TwoDSpectralCompliance.h b/src/2DSpectralCompliance/TwoDSpectralCompliance.h index b8e9bdc..5daaff1 100644 --- a/src/2DSpectralCompliance/TwoDSpectralCompliance.h +++ b/src/2DSpectralCompliance/TwoDSpectralCompliance.h @@ -4,15 +4,17 @@ #include #include #include +#include class CustomQwtPlot; class QwtPlotSpectrogram; - +class QPushButton; +class QLineEdit; +class ScatterPlotItem; namespace Ui { class TwoDSpectralCompliance; } -//// 用于存储三维数据点(初级能量,次级能量和,计数) struct TwoSurfacePoint { float primaryEnergy; float secondaryEnergySum; @@ -29,6 +31,9 @@ public: virtual void InitViewWorkspace(const QString& project_name) override final; virtual void SetAnalyzeDataFilename(const QMap& data_files_set) override; +protected: + void resizeEvent(QResizeEvent *event) override; + bool eventFilter(QObject *obj, QEvent *event) override; private: void setupPlot(); @@ -36,12 +41,23 @@ private: void generateSurfaceData(); void updateSpectrogram(); + void createFloatingInfoWidget(); + void updateInfoContent(); + void updateToggleButtonText(); + void updateFloatingWidgetPosition(); + void updateToggleButtonPosition(); + void updateShowButtonPosition(); + +private slots: + void showFloatingWidget(); + void hideFloatingWidget(); + + private: Ui::TwoDSpectralCompliance *ui; CustomQwtPlot* _plot = nullptr; QwtPlotSpectrogram* _spectrogram = nullptr; - // 原始数据 struct EventData { int eventId; int board; @@ -49,8 +65,21 @@ private: double energy; unsigned long long timeCounter; }; - QVector m_rawData; // 从 CSV 读取的原始数据 - QVector m_surfaceData; // 生成的曲面点(每个事件一个点,计数累加) + QVector m_rawData; + QVector m_surfaceData; + + QWidget* m_floatingWidget = nullptr; + QPushButton* m_toggleButton = nullptr; + QPushButton* m_showButton = nullptr; + + QLineEdit* m_totalEventsEdit = nullptr; + QLineEdit* m_totalPointsEdit = nullptr; + QLineEdit* m_maxCountEdit = nullptr; + QLineEdit* m_primRangeEdit = nullptr; + QLineEdit* m_secRangeEdit = nullptr; + + QPoint m_dragPosition; + bool m_dragging = false; }; #endif // TWODSPECTRALCOMPLIANCE_H diff --git a/src/ConformToTheEnergySpectrum/ConformToTheEnergySpectrum.cpp b/src/ConformToTheEnergySpectrum/ConformToTheEnergySpectrum.cpp new file mode 100644 index 0000000..b4f4701 --- /dev/null +++ b/src/ConformToTheEnergySpectrum/ConformToTheEnergySpectrum.cpp @@ -0,0 +1,216 @@ +#include "ConformToTheEnergySpectrum.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; +}; + +struct CoincidenceEvent +{ + std::vector events; +}; + +ConformToTheEnergySpectrum::ConformToTheEnergySpectrum(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); +} + +ConformToTheEnergySpectrum::~ConformToTheEnergySpectrum() +{ +} + +void ConformToTheEnergySpectrum::InitViewWorkspace(const QString &project_name) +{ + Q_UNUSED(project_name); +} + +void ConformToTheEnergySpectrum::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(); + } +} + +static std::vector processCoincidence(const std::vector& data, + uint64_t time_window_ns = 50, + int min_order = 2, + int max_order = 9) +{ + std::vector result; + if (data.empty()) return result; + + std::vector sorted = data; + std::sort(sorted.begin(), sorted.end(), + [](const SpectrumData& a, const SpectrumData& b) { return a.timestamp < b.timestamp; }); + + size_t n = sorted.size(); + for (size_t i = 0; i < n; ++i) + { + std::vector cluster; + cluster.push_back(sorted[i]); + uint64_t base = sorted[i].timestamp; + + for (size_t j = i + 1; j < n && (sorted[j].timestamp - base) <= time_window_ns; ++j) + cluster.push_back(sorted[j]); + for (size_t j = i; j > 0 && (base - sorted[j-1].timestamp) <= time_window_ns; --j) + if (j-1 != i) cluster.push_back(sorted[j-1]); + + std::sort(cluster.begin(), cluster.end(), + [](const SpectrumData& a, const SpectrumData& b) { return a.timestamp < b.timestamp; }); + cluster.erase(std::unique(cluster.begin(), cluster.end(), + [](const SpectrumData& a, const SpectrumData& b) { + return a.timestamp == b.timestamp && a.board_id == b.board_id && a.channel_id == b.channel_id; + }), cluster.end()); + + int order = (int)cluster.size(); + if (order >= min_order && order <= max_order) + { + CoincidenceEvent ev; + ev.events = cluster; + result.push_back(ev); + i += (cluster.size() - 1); + } + } + return result; +} + +void ConformToTheEnergySpectrum::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 uint64_t TIME_WINDOW_NS = 50; + const int MIN_ORDER = 2; + const int MAX_ORDER = 9; + std::vector coincidences = processCoincidence(rawData, TIME_WINDOW_NS, MIN_ORDER, MAX_ORDER); + + if (coincidences.empty()) { + _busy_indicator->Stop(); + return; + } + + const int STEP = 1; + std::map hist; + + for (const auto& ev : coincidences) { + for (const auto& spdt : ev.events) { + 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 ConformToTheEnergySpectrum::showEvent(QShowEvent *e) +{ + Q_UNUSED(e); + if (_busy_indicator) { + _busy_indicator->setGeometry(this->rect()); + this->update(); + } +} + + diff --git a/src/ConformToTheEnergySpectrum/ConformToTheEnergySpectrum.h b/src/ConformToTheEnergySpectrum/ConformToTheEnergySpectrum.h new file mode 100644 index 0000000..c8db7fb --- /dev/null +++ b/src/ConformToTheEnergySpectrum/ConformToTheEnergySpectrum.h @@ -0,0 +1,34 @@ +#ifndef CONFORMTOTHEENERGYSPECTRUM_H +#define CONFORMTOTHEENERGYSPECTRUM_H + +#include "MeasureAnalysisView.h" + +class CustomQwtPlot; +class QwtPlotCurve; +class BusyIndicator; + +class ConformToTheEnergySpectrum : public MeasureAnalysisView +{ + Q_OBJECT +public: + explicit ConformToTheEnergySpectrum(QWidget *parent = nullptr); + virtual ~ConformToTheEnergySpectrum(); + 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 // CONFORMTOTHEENERGYSPECTRUM_H + + diff --git a/src/MeasureAnalysisTreeView.cpp b/src/MeasureAnalysisTreeView.cpp index 6d008d8..e554378 100644 --- a/src/MeasureAnalysisTreeView.cpp +++ b/src/MeasureAnalysisTreeView.cpp @@ -260,6 +260,15 @@ void MeasureAnalysisTreeView::onNodeDoubleClicked(const QModelIndex& index) } } } break; + case AnalysisType::CoincidenceParticleEnergySpectrumView: { + MeasureAnalysisProjectModel* project_model = _model->GetProjectModel(project_name); + if (project_model) { + auto file_name_list = project_model->GetTimeWinConformEnergyDataFilenameList(project_model->GetConformTimeWin()); + for (auto it = file_name_list.constBegin(); it!=file_name_list.constEnd(); ++it) { + data_files_set[QString::number(it.key())] = it.value(); + } + } + } break; default: break; } diff --git a/src/MeasureAnalysisView.cpp b/src/MeasureAnalysisView.cpp index b92294d..66708cd 100644 --- a/src/MeasureAnalysisView.cpp +++ b/src/MeasureAnalysisView.cpp @@ -9,6 +9,7 @@ #include "ParticleInjectTimeAnalysisView.h" #include "ParticleTimeDifferenceView.h" #include "TwoDSpectralCompliance.h" +#include "ConformToTheEnergySpectrum.h" #include MeasureAnalysisView* MeasureAnalysisView::NewAnalyzeView(AnalysisType view_type) @@ -96,8 +97,8 @@ MeasureAnalysisView* MeasureAnalysisView::NewAnalyzeView(AnalysisType view_type) // new_view->setDeleteOnClose(false); } break; case AnalysisType::CoincidenceParticleEnergySpectrumView: { - // new_view = new MeasureAnalysisDataTableView; - // new_view->setDeleteOnClose(false); + new_view = new ConformToTheEnergySpectrum; + new_view->setDeleteOnClose(false); } break; case AnalysisType::AntiCoincidenceSpectrumView: { // new_view = new MeasureAnalysisDataTableView; diff --git a/src/ThreeDimensionalConformityAnalysisView/ThreeDDisplay.cpp b/src/ThreeDimensionalConformityAnalysisView/ThreeDDisplay.cpp index b137b8b..02f1335 100644 --- a/src/ThreeDimensionalConformityAnalysisView/ThreeDDisplay.cpp +++ b/src/ThreeDimensionalConformityAnalysisView/ThreeDDisplay.cpp @@ -13,7 +13,12 @@ ThreeDDisplay::ThreeDDisplay(QWidget *parent) : ThreeDDisplay::~ThreeDDisplay() { + delete ui; +// if(m_surface != nullptr) delete m_surface; +// if(m_dataProxy != nullptr) delete m_dataProxy; +// if(m_series != nullptr) delete m_series; +// if(m_surfaceContainer != nullptr) delete m_surfaceContainer; } void ThreeDDisplay::_init3DSurface() diff --git a/src/src.pro b/src/src.pro index 7a73a57..1d04ea3 100644 --- a/src/src.pro +++ b/src/src.pro @@ -36,7 +36,9 @@ INCLUDEPATH += \ $${PWD}/MeasureAnalysisHistoryForm \ $${PWD}/MeasureDeviceParamsConfigView \ $${PWD}/DeviceParameterConfig \ - $${PWD}/2DSpectralCompliance + $${PWD}/2DSpectralCompliance \ + $${PWD}/ConformToTheEnergySpectrum + DEPENDPATH += \ $${PWD}/BusyIndicator \ @@ -52,7 +54,9 @@ DEPENDPATH += \ $${PWD}/MeasureAnalysisHistoryForm \ $${PWD}/MeasureDeviceParamsConfigView \ $${PWD}/DeviceParameterConfig \ - $${PWD}/2DSpectralCompliance + $${PWD}/2DSpectralCompliance \ + $${PWD}/ConformToTheEnergySpectrum + @@ -95,6 +99,7 @@ SOURCES += \ ThreeDimensionalConformityAnalysisView/ThreeDDisplay.cpp \ EnergyCountPeakFitView/EnergyCountPeakFitView.cpp \ DeviceParameterConfig/DeviceParameterProxy.cpp \ + ConformToTheEnergySpectrum/ConformToTheEnergySpectrum.cpp \ main.cpp HEADERS += \ @@ -138,7 +143,9 @@ HEADERS += \ ThreeDimensionalConformityAnalysisView/ParticleDataStatistics.h \ ThreeDimensionalConformityAnalysisView/ThreeDDisplay.h \ EnergyCountPeakFitView/EnergyCountPeakFitView.h \ - DeviceParameterConfig/DeviceParameterProxy.h + DeviceParameterConfig/DeviceParameterProxy.h \ + ConformToTheEnergySpectrum/ConformToTheEnergySpectrum.h \ +