二维符合能谱成员变量存储数据优化,二维符合能谱框选区域显示统计信息,二维符合能谱增加右键菜单还原
This commit is contained in:
parent
e7f7e31d85
commit
3a8825beb9
|
|
@ -19,8 +19,11 @@
|
||||||
#include <QwtLinearColorMap>
|
#include <QwtLinearColorMap>
|
||||||
#include <QwtMatrixRasterData>
|
#include <QwtMatrixRasterData>
|
||||||
#include <QwtPlotCanvas>
|
#include <QwtPlotCanvas>
|
||||||
|
#include <QwtPlotPicker>
|
||||||
#include <QwtPlotSpectrogram>
|
#include <QwtPlotSpectrogram>
|
||||||
|
#include <QwtScaleMap>
|
||||||
#include <QwtText>
|
#include <QwtText>
|
||||||
|
#include <qwt_picker_machine.h>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
|
|
@ -45,6 +48,8 @@ TwoDSpectralCompliance::TwoDSpectralCompliance(QWidget* parent)
|
||||||
, ui(new Ui::TwoDSpectralCompliance)
|
, ui(new Ui::TwoDSpectralCompliance)
|
||||||
{
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
this->_menu = new QMenu(this);
|
||||||
|
setupMenu();
|
||||||
QHBoxLayout* layout = new QHBoxLayout(this);
|
QHBoxLayout* layout = new QHBoxLayout(this);
|
||||||
layout->setContentsMargins(0, 0, 0, 0);
|
layout->setContentsMargins(0, 0, 0, 0);
|
||||||
this->_plot = new CustomQwtPlot(this);
|
this->_plot = new CustomQwtPlot(this);
|
||||||
|
|
@ -79,8 +84,8 @@ void TwoDSpectralCompliance::SetAnalyzeDataFilename(const QMap<QString, QVariant
|
||||||
|
|
||||||
_busy_indicator->Start();
|
_busy_indicator->Start();
|
||||||
auto functionToRun = [this, _data_filenames]() {
|
auto functionToRun = [this, _data_filenames]() {
|
||||||
readCsv(_data_filenames);
|
QVector<EventData> rawData = readCsv(_data_filenames);
|
||||||
generateSurfaceData();
|
generateSurfaceData(rawData);
|
||||||
QMetaObject::invokeMethod(this, [this]() {
|
QMetaObject::invokeMethod(this, [this]() {
|
||||||
updateSpectrogram();
|
updateSpectrogram();
|
||||||
_busy_indicator->Stop();
|
_busy_indicator->Stop();
|
||||||
|
|
@ -122,15 +127,45 @@ void TwoDSpectralCompliance::setupPlot()
|
||||||
_spectrogram = new QwtPlotSpectrogram();
|
_spectrogram = new QwtPlotSpectrogram();
|
||||||
_spectrogram->setColorMap(new HeatMapColorMap());
|
_spectrogram->setColorMap(new HeatMapColorMap());
|
||||||
_spectrogram->attach(_plot);
|
_spectrogram->attach(_plot);
|
||||||
|
|
||||||
|
_picker = new QwtPlotPicker(
|
||||||
|
QwtPlot::xBottom, // X 轴
|
||||||
|
QwtPlot::yLeft, // Y 轴
|
||||||
|
QwtPicker::RectRubberBand, // 橡皮筋样式
|
||||||
|
QwtPicker::AlwaysOff, // 不显示坐标追踪
|
||||||
|
_plot->canvas() // 作用于画布
|
||||||
|
);
|
||||||
|
QwtPickerDragRectMachine* rectMachine = new QwtPickerDragRectMachine();
|
||||||
|
_picker->setStateMachine(rectMachine);
|
||||||
|
connect(_picker, SIGNAL(selected(const QRectF&)),
|
||||||
|
this, SLOT(onSelection(const QRectF&)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void TwoDSpectralCompliance::readCsv(const QStringList& filename)
|
void TwoDSpectralCompliance::setupMenu()
|
||||||
{
|
{
|
||||||
|
this->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||||
|
connect(this, &TwoDSpectralCompliance::customContextMenuRequested, [this](const QPoint& pos) {
|
||||||
|
this->_menu->exec(this->mapToGlobal(pos));
|
||||||
|
});
|
||||||
|
QAction* action_plot_reset = this->_menu->addAction(QStringLiteral(u"还原"));
|
||||||
|
action_plot_reset->setObjectName("plot_reset");
|
||||||
|
connect(action_plot_reset, &QAction::triggered, [this]() {
|
||||||
|
this->_plot->ResetPlot();
|
||||||
|
});
|
||||||
|
this->_menu->addSeparator();
|
||||||
|
QAction* action_plot_config = this->_menu->addAction(QStringLiteral(u"图表配置"));
|
||||||
|
action_plot_config->setObjectName("plot_config");
|
||||||
|
connect(action_plot_config, &QAction::triggered, this, &TwoDSpectralCompliance::onActionPlotConfigure);
|
||||||
|
}
|
||||||
|
|
||||||
|
QVector<EventData> TwoDSpectralCompliance::readCsv(const QStringList& filename)
|
||||||
|
{
|
||||||
|
QVector<EventData> rawData;
|
||||||
if (filename.isEmpty()) {
|
if (filename.isEmpty()) {
|
||||||
QMetaObject::invokeMethod(this, [this]() {
|
QMetaObject::invokeMethod(this, [this]() {
|
||||||
_busy_indicator->Stop();
|
_busy_indicator->Stop();
|
||||||
}, Qt::QueuedConnection);
|
}, Qt::QueuedConnection);
|
||||||
return;
|
return rawData;
|
||||||
}
|
}
|
||||||
for (const QString& filename : filename) {
|
for (const QString& filename : filename) {
|
||||||
io::CSVReader<5> in(QStrToSysPath(filename));
|
io::CSVReader<5> in(QStrToSysPath(filename));
|
||||||
|
|
@ -150,19 +185,21 @@ void TwoDSpectralCompliance::readCsv(const QStringList& filename)
|
||||||
sd.channel = channel;
|
sd.channel = channel;
|
||||||
sd.energy = energy;
|
sd.energy = energy;
|
||||||
sd.timeCounter = time_count;
|
sd.timeCounter = time_count;
|
||||||
m_rawData.push_back(sd);
|
rawData.push_back(sd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return rawData;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TwoDSpectralCompliance::generateSurfaceData()
|
void TwoDSpectralCompliance::generateSurfaceData(QVector<EventData> rawData)
|
||||||
{
|
{
|
||||||
m_surfaceData.clear();
|
m_surfaceData.clear();
|
||||||
if (m_rawData.isEmpty())
|
m_eventSummaries.clear();
|
||||||
|
if (rawData.isEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
QMap<int, QVector<EventData>> eventMap;
|
QMap<int, QVector<EventData>> eventMap;
|
||||||
for (const auto& ev : m_rawData) {
|
for (const auto& ev : rawData) {
|
||||||
eventMap[ev.eventId].append(ev);
|
eventMap[ev.eventId].append(ev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -179,6 +216,12 @@ void TwoDSpectralCompliance::generateSurfaceData()
|
||||||
secondarySum += events[i].energy;
|
secondarySum += events[i].energy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EventSummary summary;
|
||||||
|
summary.eventId = it.key();
|
||||||
|
summary.primaryEnergy = primaryEnergy;
|
||||||
|
summary.secondaryEnergySum = secondarySum;
|
||||||
|
m_eventSummaries.append(summary);
|
||||||
|
|
||||||
auto key = qMakePair(primaryEnergy, secondarySum);
|
auto key = qMakePair(primaryEnergy, secondarySum);
|
||||||
countMap[key]++;
|
countMap[key]++;
|
||||||
}
|
}
|
||||||
|
|
@ -242,17 +285,23 @@ void TwoDSpectralCompliance::updateSpectrogram()
|
||||||
QwtMatrixRasterData* data = new QwtMatrixRasterData();
|
QwtMatrixRasterData* data = new QwtMatrixRasterData();
|
||||||
data->setInterval(Qt::XAxis, QwtInterval(primStart, primEnd));
|
data->setInterval(Qt::XAxis, QwtInterval(primStart, primEnd));
|
||||||
data->setInterval(Qt::YAxis, QwtInterval(secStart, secEnd));
|
data->setInterval(Qt::YAxis, QwtInterval(secStart, secEnd));
|
||||||
|
_plot->SetAxisInitRange(QwtPlot::xBottom, primStart, primEnd);
|
||||||
|
_plot->SetAxisInitRange(QwtPlot::yLeft, secStart, secEnd);
|
||||||
data->setInterval(Qt::ZAxis, QwtInterval(0, maxCount));
|
data->setInterval(Qt::ZAxis, QwtInterval(0, maxCount));
|
||||||
data->setValueMatrix(zValues, numCols);
|
data->setValueMatrix(zValues, numCols);
|
||||||
|
|
||||||
_spectrogram->setData(data);
|
_spectrogram->setData(data);
|
||||||
_plot->setAxisScale(QwtPlot::xBottom, primStart, primEnd);
|
_plot->setAxisScale(QwtPlot::xBottom, primStart, primEnd);
|
||||||
_plot->setAxisScale(QwtPlot::yLeft, secStart, secEnd);
|
_plot->setAxisScale(QwtPlot::yLeft, secStart, secEnd);
|
||||||
|
m_globalXMin = primStart;
|
||||||
|
m_globalXMax = primEnd;
|
||||||
|
m_globalYMin = secStart;
|
||||||
|
m_globalYMax = secEnd;
|
||||||
_plot->replot();
|
_plot->replot();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TwoDSpectralCompliance::createFloatingInfoWidget()
|
void TwoDSpectralCompliance::createFloatingInfoWidget()
|
||||||
{
|
{
|
||||||
// 悬浮窗口
|
|
||||||
m_floatingWidget = new QWidget(this);
|
m_floatingWidget = new QWidget(this);
|
||||||
m_floatingWidget->setObjectName("FloatingInfoWidget");
|
m_floatingWidget->setObjectName("FloatingInfoWidget");
|
||||||
m_floatingWidget->setStyleSheet(
|
m_floatingWidget->setStyleSheet(
|
||||||
|
|
@ -268,7 +317,7 @@ void TwoDSpectralCompliance::createFloatingInfoWidget()
|
||||||
mainLayout->setSpacing(5);
|
mainLayout->setSpacing(5);
|
||||||
mainLayout->setContentsMargins(8, 8, 8, 8);
|
mainLayout->setContentsMargins(8, 8, 8, 8);
|
||||||
|
|
||||||
// 标题栏(可拖动,并包含隐藏按钮)
|
// 标题栏(可拖动,包含重置和隐藏按钮)
|
||||||
QWidget* titleBar = new QWidget();
|
QWidget* titleBar = new QWidget();
|
||||||
QHBoxLayout* titleLayout = new QHBoxLayout(titleBar);
|
QHBoxLayout* titleLayout = new QHBoxLayout(titleBar);
|
||||||
titleLayout->setContentsMargins(0, 0, 0, 0);
|
titleLayout->setContentsMargins(0, 0, 0, 0);
|
||||||
|
|
@ -276,9 +325,17 @@ void TwoDSpectralCompliance::createFloatingInfoWidget()
|
||||||
titleLabel->setStyleSheet("font-weight: bold;");
|
titleLabel->setStyleSheet("font-weight: bold;");
|
||||||
titleLayout->addWidget(titleLabel);
|
titleLayout->addWidget(titleLabel);
|
||||||
titleLayout->addStretch();
|
titleLayout->addStretch();
|
||||||
QPushButton* hideBtn = new QPushButton(QStringLiteral("−"));
|
|
||||||
|
// 重置按钮:清除选区,显示全局统计
|
||||||
|
QPushButton* resetBtn = new QPushButton("重置");
|
||||||
|
resetBtn->setFixedSize(40, 20);
|
||||||
|
resetBtn->setToolTip(QStringLiteral(u"显示全局统计"));
|
||||||
|
resetBtn->setStyleSheet("border: none; font-weight: bold;");
|
||||||
|
titleLayout->addWidget(resetBtn);
|
||||||
|
|
||||||
|
// 隐藏按钮
|
||||||
|
QPushButton* hideBtn = new QPushButton(QStringLiteral("X"));
|
||||||
hideBtn->setFixedSize(20, 20);
|
hideBtn->setFixedSize(20, 20);
|
||||||
hideBtn->setText(QStringLiteral(u"X"));
|
|
||||||
hideBtn->setStyleSheet("border: none; font-weight: bold;");
|
hideBtn->setStyleSheet("border: none; font-weight: bold;");
|
||||||
titleLayout->addWidget(hideBtn);
|
titleLayout->addWidget(hideBtn);
|
||||||
mainLayout->addWidget(titleBar);
|
mainLayout->addWidget(titleBar);
|
||||||
|
|
@ -295,6 +352,7 @@ void TwoDSpectralCompliance::createFloatingInfoWidget()
|
||||||
m_totalPointsEdit = new QLineEdit;
|
m_totalPointsEdit = new QLineEdit;
|
||||||
m_totalPointsEdit->setReadOnly(true);
|
m_totalPointsEdit->setReadOnly(true);
|
||||||
m_totalPointsEdit->setFixedWidth(130);
|
m_totalPointsEdit->setFixedWidth(130);
|
||||||
|
|
||||||
m_maxCountEdit = new QLineEdit;
|
m_maxCountEdit = new QLineEdit;
|
||||||
m_maxCountEdit->setReadOnly(true);
|
m_maxCountEdit->setReadOnly(true);
|
||||||
m_maxCountEdit->setFixedWidth(130);
|
m_maxCountEdit->setFixedWidth(130);
|
||||||
|
|
@ -307,7 +365,7 @@ void TwoDSpectralCompliance::createFloatingInfoWidget()
|
||||||
m_secRangeEdit->setReadOnly(true);
|
m_secRangeEdit->setReadOnly(true);
|
||||||
m_secRangeEdit->setFixedWidth(130);
|
m_secRangeEdit->setFixedWidth(130);
|
||||||
|
|
||||||
formLayout->addRow(QStringLiteral(u"总事件数:"), m_totalEventsEdit);
|
formLayout->addRow(QStringLiteral(u"符合事件数:"), m_totalEventsEdit);
|
||||||
formLayout->addRow(QStringLiteral(u"有效数据点:"), m_totalPointsEdit);
|
formLayout->addRow(QStringLiteral(u"有效数据点:"), m_totalPointsEdit);
|
||||||
formLayout->addRow(QStringLiteral(u"最大计数:"), m_maxCountEdit);
|
formLayout->addRow(QStringLiteral(u"最大计数:"), m_maxCountEdit);
|
||||||
formLayout->addRow(QStringLiteral(u"初级能量范围:"), m_primRangeEdit);
|
formLayout->addRow(QStringLiteral(u"初级能量范围:"), m_primRangeEdit);
|
||||||
|
|
@ -317,6 +375,10 @@ void TwoDSpectralCompliance::createFloatingInfoWidget()
|
||||||
mainLayout->addStretch();
|
mainLayout->addStretch();
|
||||||
|
|
||||||
connect(hideBtn, &QPushButton::clicked, this, &TwoDSpectralCompliance::hideFloatingWidget);
|
connect(hideBtn, &QPushButton::clicked, this, &TwoDSpectralCompliance::hideFloatingWidget);
|
||||||
|
connect(resetBtn, &QPushButton::clicked, this, [this]() {
|
||||||
|
m_hasSelection = false;
|
||||||
|
updateInfoContent();
|
||||||
|
});
|
||||||
|
|
||||||
titleBar->setCursor(Qt::SizeAllCursor);
|
titleBar->setCursor(Qt::SizeAllCursor);
|
||||||
m_floatingWidget->installEventFilter(this);
|
m_floatingWidget->installEventFilter(this);
|
||||||
|
|
@ -340,7 +402,6 @@ void TwoDSpectralCompliance::createFloatingInfoWidget()
|
||||||
m_floatingWidget->hide();
|
m_floatingWidget->hide();
|
||||||
m_showButton->show();
|
m_showButton->show();
|
||||||
|
|
||||||
// m_floatingWidget->raise();
|
|
||||||
updateInfoContent();
|
updateInfoContent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -356,7 +417,7 @@ void TwoDSpectralCompliance::showFloatingWidget()
|
||||||
m_floatingWidget->show();
|
m_floatingWidget->show();
|
||||||
m_floatingWidget->raise();
|
m_floatingWidget->raise();
|
||||||
m_showButton->hide();
|
m_showButton->hide();
|
||||||
updateInfoContent(); // 刷新内容
|
updateInfoContent();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TwoDSpectralCompliance::updateShowButtonPosition()
|
void TwoDSpectralCompliance::updateShowButtonPosition()
|
||||||
|
|
@ -366,6 +427,44 @@ void TwoDSpectralCompliance::updateShowButtonPosition()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TwoDSpectralCompliance::onSelection(const QRectF& rect)
|
||||||
|
{
|
||||||
|
// 忽略过小的选区(可能是误点击)
|
||||||
|
if (rect.width() < 5 || rect.height() < 5)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// 将画布像素矩形转换为轴坐标
|
||||||
|
const QwtScaleMap xMap = _plot->canvasMap(QwtPlot::xBottom);
|
||||||
|
const QwtScaleMap yMap = _plot->canvasMap(QwtPlot::yLeft);
|
||||||
|
// qDebug()<<"左边:" << rect.left() << "右边:" << rect.right()<< "上边:" << rect.top()<< "下边:" << rect.bottom();
|
||||||
|
// double x1 = xMap.invTransform(rect.left());
|
||||||
|
// double x2 = xMap.invTransform(rect.right());
|
||||||
|
// double y1 = yMap.invTransform(rect.bottom()); // 注意画布Y轴方向
|
||||||
|
// double y2 = yMap.invTransform(rect.top());
|
||||||
|
|
||||||
|
|
||||||
|
double x1 = rect.left();
|
||||||
|
double x2 = rect.right();
|
||||||
|
double y1 = rect.bottom();
|
||||||
|
double y2 = rect.top();
|
||||||
|
m_selXMin = std::min(x1, x2);
|
||||||
|
m_selXMax = std::max(x1, x2);
|
||||||
|
m_selYMin = std::min(y1, y2);
|
||||||
|
m_selYMax = std::max(y1, y2);
|
||||||
|
|
||||||
|
_plot->setAxisScale(QwtPlot::xBottom, m_selXMin, m_selXMax);
|
||||||
|
_plot->setAxisScale(QwtPlot::yLeft, m_selYMin, m_selYMax);
|
||||||
|
_plot->replot();
|
||||||
|
|
||||||
|
m_hasSelection = true;
|
||||||
|
updateInfoContent();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TwoDSpectralCompliance::onActionPlotConfigure()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void TwoDSpectralCompliance:: updateInfoContent()
|
void TwoDSpectralCompliance:: updateInfoContent()
|
||||||
{
|
{
|
||||||
if (!m_totalEventsEdit)
|
if (!m_totalEventsEdit)
|
||||||
|
|
@ -380,11 +479,53 @@ void TwoDSpectralCompliance::updateInfoContent()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int totalPoints = m_surfaceData.size();
|
if (m_hasSelection) {
|
||||||
|
// ----- 框选区域统计(基于热图数据点 m_surfaceData)-----
|
||||||
|
int totalEvents = 0; // 总事件数 = 区域内所有点的计数值之和
|
||||||
|
int totalPoints = 0;
|
||||||
int maxCount = 0;
|
int maxCount = 0;
|
||||||
float minPrim = 1e9f, maxPrim = -1e9f;
|
float minPrim = 1e9f, maxPrim = -1e9f;
|
||||||
float minSec = 1e9f, maxSec = -1e9f;
|
float minSec = 1e9f, maxSec = -1e9f;
|
||||||
|
|
||||||
for (const auto& pt : m_surfaceData) {
|
for (const auto& pt : m_surfaceData) {
|
||||||
|
if (pt.primaryEnergy >= m_selXMin && pt.primaryEnergy <= m_selXMax &&
|
||||||
|
pt.secondaryEnergySum >= m_selYMin && pt.secondaryEnergySum <= m_selYMax) {
|
||||||
|
|
||||||
|
totalPoints++;
|
||||||
|
totalEvents += pt.count;
|
||||||
|
maxCount = std::max(maxCount, pt.count);
|
||||||
|
|
||||||
|
minPrim = std::min(minPrim, pt.primaryEnergy);
|
||||||
|
maxPrim = std::max(maxPrim, pt.primaryEnergy);
|
||||||
|
minSec = std::min(minSec, pt.secondaryEnergySum);
|
||||||
|
maxSec = std::max(maxSec, pt.secondaryEnergySum);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (totalPoints == 0) {
|
||||||
|
m_totalEventsEdit->setText(QStringLiteral(u"0"));
|
||||||
|
m_totalPointsEdit->setText(QStringLiteral(u"0"));
|
||||||
|
m_maxCountEdit->setText(QStringLiteral(u"0"));
|
||||||
|
m_primRangeEdit->setText(QStringLiteral(u"无数据"));
|
||||||
|
m_secRangeEdit->setText(QStringLiteral(u"无数据"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
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));
|
||||||
|
} else {
|
||||||
|
// ----- 全局统计(无选区时)-----
|
||||||
|
int totalPoints = m_surfaceData.size();
|
||||||
|
int totalEvents = 0;
|
||||||
|
int maxCount = 0;
|
||||||
|
float minPrim = 1e9f, maxPrim = -1e9f;
|
||||||
|
float minSec = 1e9f, maxSec = -1e9f;
|
||||||
|
|
||||||
|
for (const auto& pt : m_surfaceData) {
|
||||||
|
totalEvents += pt.count;
|
||||||
minPrim = std::min(minPrim, pt.primaryEnergy);
|
minPrim = std::min(minPrim, pt.primaryEnergy);
|
||||||
maxPrim = std::max(maxPrim, pt.primaryEnergy);
|
maxPrim = std::max(maxPrim, pt.primaryEnergy);
|
||||||
minSec = std::min(minSec, pt.secondaryEnergySum);
|
minSec = std::min(minSec, pt.secondaryEnergySum);
|
||||||
|
|
@ -392,25 +533,19 @@ void TwoDSpectralCompliance::updateInfoContent()
|
||||||
maxCount = std::max(maxCount, pt.count);
|
maxCount = std::max(maxCount, pt.count);
|
||||||
}
|
}
|
||||||
|
|
||||||
QSet<int> eventIds;
|
|
||||||
for (const auto& ev : m_rawData) {
|
|
||||||
eventIds.insert(ev.eventId);
|
|
||||||
}
|
|
||||||
int totalEvents = eventIds.size();
|
|
||||||
|
|
||||||
m_totalEventsEdit->setText(QString::number(totalEvents));
|
m_totalEventsEdit->setText(QString::number(totalEvents));
|
||||||
m_totalPointsEdit->setText(QString::number(totalPoints));
|
m_totalPointsEdit->setText(QString::number(totalPoints));
|
||||||
m_maxCountEdit->setText(QString::number(maxCount));
|
m_maxCountEdit->setText(QString::number(maxCount));
|
||||||
m_primRangeEdit->setText(QString("[%1, %2]").arg(minPrim, 0, 'f', 2).arg(maxPrim, 0, 'f', 2));
|
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));
|
m_secRangeEdit->setText(QString("[%1, %2]").arg(minSec, 0, 'f', 2).arg(maxSec, 0, 'f', 2));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void TwoDSpectralCompliance::resizeEvent(QResizeEvent* event)
|
void TwoDSpectralCompliance::resizeEvent(QResizeEvent* event)
|
||||||
{
|
{
|
||||||
QWidget::resizeEvent(event);
|
QWidget::resizeEvent(event);
|
||||||
updateShowButtonPosition();
|
updateShowButtonPosition();
|
||||||
if (m_floatingWidget && m_floatingWidget->isVisible()) {
|
if (m_floatingWidget && m_floatingWidget->isVisible()) {
|
||||||
// 限制悬浮窗口不超出父窗口边界
|
|
||||||
QRect rect = m_floatingWidget->geometry();
|
QRect rect = m_floatingWidget->geometry();
|
||||||
int newX = qBound(0, rect.x(), width() - rect.width());
|
int newX = qBound(0, rect.x(), width() - rect.width());
|
||||||
int newY = qBound(0, rect.y(), height() - rect.height());
|
int newY = qBound(0, rect.y(), height() - rect.height());
|
||||||
|
|
|
||||||
|
|
@ -5,9 +5,10 @@
|
||||||
#include <QPoint>
|
#include <QPoint>
|
||||||
#include <QVector>
|
#include <QVector>
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
#include <QMenu>
|
||||||
class CustomQwtPlot;
|
class CustomQwtPlot;
|
||||||
class QwtPlotSpectrogram;
|
class QwtPlotSpectrogram;
|
||||||
|
class QwtPlotPicker;
|
||||||
class QPushButton;
|
class QPushButton;
|
||||||
class QLineEdit;
|
class QLineEdit;
|
||||||
class ScatterPlotItem;
|
class ScatterPlotItem;
|
||||||
|
|
@ -22,6 +23,14 @@ struct TwoSurfacePoint {
|
||||||
int count;
|
int count;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct EventData {
|
||||||
|
int eventId;
|
||||||
|
int board;
|
||||||
|
int channel;
|
||||||
|
double energy;
|
||||||
|
unsigned long long timeCounter;
|
||||||
|
};
|
||||||
|
|
||||||
class TwoDSpectralCompliance : public MeasureAnalysisView {
|
class TwoDSpectralCompliance : public MeasureAnalysisView {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
|
|
@ -39,8 +48,9 @@ protected:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setupPlot();
|
void setupPlot();
|
||||||
void readCsv(const QStringList& filename);
|
void setupMenu();
|
||||||
void generateSurfaceData();
|
QVector<EventData> readCsv(const QStringList& filename);
|
||||||
|
void generateSurfaceData(QVector<EventData> rawData);
|
||||||
void updateSpectrogram();
|
void updateSpectrogram();
|
||||||
|
|
||||||
void createFloatingInfoWidget();
|
void createFloatingInfoWidget();
|
||||||
|
|
@ -53,21 +63,32 @@ private:
|
||||||
private slots:
|
private slots:
|
||||||
void showFloatingWidget();
|
void showFloatingWidget();
|
||||||
void hideFloatingWidget();
|
void hideFloatingWidget();
|
||||||
|
void onSelection(const QRectF& rect);
|
||||||
|
void onActionPlotConfigure();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ui::TwoDSpectralCompliance* ui;
|
Ui::TwoDSpectralCompliance* ui;
|
||||||
|
QMenu* _menu = nullptr;
|
||||||
CustomQwtPlot* _plot = nullptr;
|
CustomQwtPlot* _plot = nullptr;
|
||||||
QwtPlotSpectrogram* _spectrogram = nullptr;
|
QwtPlotSpectrogram* _spectrogram = nullptr;
|
||||||
|
QwtPlotPicker* _picker = nullptr;
|
||||||
|
|
||||||
struct EventData {
|
|
||||||
|
|
||||||
|
struct EventSummary {
|
||||||
int eventId;
|
int eventId;
|
||||||
int board;
|
float primaryEnergy;
|
||||||
int channel;
|
float secondaryEnergySum;
|
||||||
double energy;
|
|
||||||
unsigned long long timeCounter;
|
|
||||||
};
|
};
|
||||||
QVector<EventData> m_rawData;
|
|
||||||
|
// QVector<EventData> m_rawData;
|
||||||
QVector<TwoSurfacePoint> m_surfaceData;
|
QVector<TwoSurfacePoint> m_surfaceData;
|
||||||
|
QVector<EventSummary> m_eventSummaries;
|
||||||
|
|
||||||
|
// 框选区域
|
||||||
|
bool m_hasSelection = false;
|
||||||
|
double m_selXMin = 0.0, m_selXMax = 0.0;
|
||||||
|
double m_selYMin = 0.0, m_selYMax = 0.0;
|
||||||
|
|
||||||
QWidget* m_floatingWidget = nullptr;
|
QWidget* m_floatingWidget = nullptr;
|
||||||
QPushButton* m_toggleButton = nullptr;
|
QPushButton* m_toggleButton = nullptr;
|
||||||
|
|
@ -82,6 +103,10 @@ private:
|
||||||
QPoint m_dragPosition;
|
QPoint m_dragPosition;
|
||||||
bool m_dragging = false;
|
bool m_dragging = false;
|
||||||
BusyIndicator* _busy_indicator = nullptr;
|
BusyIndicator* _busy_indicator = nullptr;
|
||||||
|
|
||||||
|
// 保存全局轴范围(用于重置放大)
|
||||||
|
double m_globalXMin = 0.0, m_globalXMax = 0.0;
|
||||||
|
double m_globalYMin = 0.0, m_globalYMax = 0.0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // TWODSPECTRALCOMPLIANCE_H
|
#endif // TWODSPECTRALCOMPLIANCE_H
|
||||||
|
|
@ -33,11 +33,11 @@ void NuclideEditDialog::initUI()
|
||||||
m_leChildNuclide = new QLineEdit(this);
|
m_leChildNuclide = new QLineEdit(this);
|
||||||
|
|
||||||
// 设置表单项(标签不变,用户界面无感知)
|
// 设置表单项(标签不变,用户界面无感知)
|
||||||
formLayout->addRow("核素名称", m_leName);
|
formLayout->addRow("核素名称:", m_leName);
|
||||||
formLayout->addRow("半衰期", m_leHalfLife);
|
formLayout->addRow("半衰期:", m_leHalfLife);
|
||||||
formLayout->addRow("半衰期不确定度", m_leHalfLifeUnc);
|
formLayout->addRow("半衰期不确定度:", m_leHalfLifeUnc);
|
||||||
formLayout->addRow("母体核素名称", m_leParentNuclide);
|
formLayout->addRow("母体核素名称:", m_leParentNuclide);
|
||||||
formLayout->addRow("子体核素名称", m_leChildNuclide);
|
formLayout->addRow("子体核素名称:", m_leChildNuclide);
|
||||||
|
|
||||||
// 按钮盒
|
// 按钮盒
|
||||||
QDialogButtonBox *btnBox = new QDialogButtonBox(
|
QDialogButtonBox *btnBox = new QDialogButtonBox(
|
||||||
|
|
|
||||||
|
|
@ -31,32 +31,32 @@ void NuclideRayDialog::initUI()
|
||||||
// 射线类型下拉框(常用核素射线类型)
|
// 射线类型下拉框(常用核素射线类型)
|
||||||
m_cmbRayType = new QComboBox(this);
|
m_cmbRayType = new QComboBox(this);
|
||||||
m_cmbRayType->addItems({QStringLiteral(u"γ"), QStringLiteral(u"β⁻"), QStringLiteral(u"β⁺"), QStringLiteral(u"α"), QStringLiteral(u"X射线"), QStringLiteral(u"中子"), QStringLiteral(u"电子俘获")});
|
m_cmbRayType->addItems({QStringLiteral(u"γ"), QStringLiteral(u"β⁻"), QStringLiteral(u"β⁺"), QStringLiteral(u"α"), QStringLiteral(u"X射线"), QStringLiteral(u"中子"), QStringLiteral(u"电子俘获")});
|
||||||
formLayout->addRow(QStringLiteral(u"射线类型"), m_cmbRayType);
|
formLayout->addRow(QStringLiteral(u"射线类型:"), m_cmbRayType);
|
||||||
|
|
||||||
m_leRayMev = new QLineEdit(this);
|
m_leRayMev = new QLineEdit(this);
|
||||||
m_leRayMev->setPlaceholderText(QStringLiteral(u"例如:1.332 MeV"));
|
m_leRayMev->setPlaceholderText(QStringLiteral(u"例如:1.332 MeV"));
|
||||||
formLayout->addRow(QStringLiteral(u"射线能量"), m_leRayMev);
|
formLayout->addRow(QStringLiteral(u"射线能量:"), m_leRayMev);
|
||||||
|
|
||||||
m_leRayMevUnc = new QLineEdit(this);
|
m_leRayMevUnc = new QLineEdit(this);
|
||||||
m_leRayMevUnc->setPlaceholderText(QStringLiteral(u"例如:0.001 MeV"));
|
m_leRayMevUnc->setPlaceholderText(QStringLiteral(u"例如:0.001 MeV"));
|
||||||
formLayout->addRow(QStringLiteral(u"能量不确定度"), m_leRayMevUnc);
|
formLayout->addRow(QStringLiteral(u"能量不确定度:"), m_leRayMevUnc);
|
||||||
|
|
||||||
m_leBranchRatio = new QLineEdit(this);
|
m_leBranchRatio = new QLineEdit(this);
|
||||||
m_leBranchRatio->setPlaceholderText(QStringLiteral(u"例如:0.9998"));
|
m_leBranchRatio->setPlaceholderText(QStringLiteral(u"例如:0.9998"));
|
||||||
formLayout->addRow("分支比", m_leBranchRatio);
|
formLayout->addRow("分支比:", m_leBranchRatio);
|
||||||
|
|
||||||
m_leBranchRatioUnc = new QLineEdit(this);
|
m_leBranchRatioUnc = new QLineEdit(this);
|
||||||
m_leBranchRatioUnc->setPlaceholderText(QStringLiteral(u"例如:0.0001"));
|
m_leBranchRatioUnc->setPlaceholderText(QStringLiteral(u"例如:0.0001"));
|
||||||
formLayout->addRow(QStringLiteral(u"分支比不确定度"), m_leBranchRatioUnc);
|
formLayout->addRow(QStringLiteral(u"分支比不确定度:"), m_leBranchRatioUnc);
|
||||||
|
|
||||||
// 主射线标识下拉框
|
// 主射线标识下拉框
|
||||||
m_cmbMainRayIdent = new QComboBox(this);
|
m_cmbMainRayIdent = new QComboBox(this);
|
||||||
m_cmbMainRayIdent->addItems({QStringLiteral(u"是"), QStringLiteral(u"否")});
|
m_cmbMainRayIdent->addItems({QStringLiteral(u"是"), QStringLiteral(u"否")});
|
||||||
formLayout->addRow(QStringLiteral(u"是否为主射线"), m_cmbMainRayIdent);
|
formLayout->addRow(QStringLiteral(u"是否为主射线:"), m_cmbMainRayIdent);
|
||||||
|
|
||||||
m_leJiahePeak = new QLineEdit(this);
|
m_leJiahePeak = new QLineEdit(this);
|
||||||
m_leJiahePeak->setPlaceholderText(QStringLiteral(u"无则留空"));
|
m_leJiahePeak->setPlaceholderText(QStringLiteral(u"无则留空"));
|
||||||
formLayout->addRow(QStringLiteral(u"加和峰"), m_leJiahePeak);
|
formLayout->addRow(QStringLiteral(u"加和峰:"), m_leJiahePeak);
|
||||||
|
|
||||||
// 按钮盒
|
// 按钮盒
|
||||||
QDialogButtonBox *btnBox = new QDialogButtonBox(
|
QDialogButtonBox *btnBox = new QDialogButtonBox(
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user