Merge branch 'dev' of http://git.hivekion.com:3000/xuhai_cpp/EnergySpectrumAnalyer into dev_xuh
This commit is contained in:
commit
653ee44f1a
214
src/CoincidenceEventTimeView/CoincidenceEventTimeView.cpp
Normal file
214
src/CoincidenceEventTimeView/CoincidenceEventTimeView.cpp
Normal file
|
|
@ -0,0 +1,214 @@
|
||||||
|
#include "CoincidenceEventTimeView.h"
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
#include <QwtPlotCurve>
|
||||||
|
#include <QwtPlotCanvas>
|
||||||
|
#include <QwtText>
|
||||||
|
#include "CustomQwtPlot.h"
|
||||||
|
#include <GlobalDefine.h>
|
||||||
|
#include "csv.h"
|
||||||
|
#include <QFileInfo>
|
||||||
|
#include <QThread>
|
||||||
|
#include "BusyIndicator.h"
|
||||||
|
#include <map>
|
||||||
|
#include <vector>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <QPen>
|
||||||
|
struct SpectrumData
|
||||||
|
{
|
||||||
|
int eventId;//事件ID
|
||||||
|
int board_id;
|
||||||
|
int channel_id;
|
||||||
|
double energy;
|
||||||
|
uint64_t timestamp;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
CoincidenceEventTimeView::CoincidenceEventTimeView(QWidget *parent) :
|
||||||
|
MeasureAnalysisView(parent)
|
||||||
|
{
|
||||||
|
this->setViewType(PlotFrame);
|
||||||
|
|
||||||
|
_plot = new CustomQwtPlot();
|
||||||
|
QVBoxLayout* layout = new QVBoxLayout(this);
|
||||||
|
layout->addWidget(_plot);
|
||||||
|
this->_menu = new QMenu(this);
|
||||||
|
setupMenu();
|
||||||
|
_plot->setCanvasBackground(Qt::white);
|
||||||
|
QwtPlotCanvas* canvas = qobject_cast<QwtPlotCanvas*>(_plot->canvas());
|
||||||
|
canvas->setFrameStyle(QFrame::NoFrame);
|
||||||
|
|
||||||
|
QFont font = this->font();
|
||||||
|
font.setBold(false);
|
||||||
|
QwtText x_label = QStringLiteral(u"符合事件初级粒子时间");
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
CoincidenceEventTimeView::~CoincidenceEventTimeView()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void CoincidenceEventTimeView::InitViewWorkspace(const QString &project_name)
|
||||||
|
{
|
||||||
|
Q_UNUSED(project_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CoincidenceEventTimeView::SetAnalyzeDataFilename(const QMap<QString, QVariant> &data_files_set)
|
||||||
|
{
|
||||||
|
_data_filenames.clear();
|
||||||
|
|
||||||
|
for (const QVariant& file_value : data_files_set) {
|
||||||
|
QString filename = file_value.toString();
|
||||||
|
if (!filename.isEmpty() && QFileInfo(filename).exists()) {
|
||||||
|
_data_filenames.append(filename);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_data_filenames.isEmpty()) {
|
||||||
|
loadAndProcess();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CoincidenceEventTimeView::loadAndProcess()
|
||||||
|
{
|
||||||
|
auto functionToRun = [this]() {
|
||||||
|
if (_data_filenames.isEmpty()) return;
|
||||||
|
|
||||||
|
_busy_indicator->Start();
|
||||||
|
|
||||||
|
std::vector<SpectrumData> rawData;
|
||||||
|
|
||||||
|
for (const QString& filename : _data_filenames) {
|
||||||
|
io::CSVReader<5> in(QStrToSysPath(filename));
|
||||||
|
in.read_header(io::ignore_extra_column,
|
||||||
|
QString(QStringLiteral(u"事件ID")).toStdString(),
|
||||||
|
QString(QStringLiteral(u"板卡号")).toStdString(),
|
||||||
|
QString(QStringLiteral(u"通道号")).toStdString(),
|
||||||
|
QString(QStringLiteral(u"能量(KeV)")).toStdString(),
|
||||||
|
QString(QStringLiteral(u"时间计数")).toStdString());
|
||||||
|
|
||||||
|
int eventId,board, channel;
|
||||||
|
double energy;
|
||||||
|
unsigned long long time_count;
|
||||||
|
while (in.read_row(eventId,board, channel, energy, time_count)) {
|
||||||
|
SpectrumData sd;
|
||||||
|
sd.eventId = eventId;
|
||||||
|
sd.board_id = board;
|
||||||
|
sd.channel_id = channel;
|
||||||
|
sd.energy = energy;
|
||||||
|
sd.timestamp = time_count;
|
||||||
|
rawData.push_back(sd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!rawData.empty()) {
|
||||||
|
std::sort(rawData.begin(), rawData.end(),
|
||||||
|
[](const SpectrumData& a, const SpectrumData& b) {
|
||||||
|
return a.eventId < b.eventId;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (rawData.empty()) {
|
||||||
|
_busy_indicator->Stop();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int eventId = 0;
|
||||||
|
QList<SpectrumData> SpectrumDataList;
|
||||||
|
for (const auto& spdt : rawData)
|
||||||
|
{
|
||||||
|
// 第一个事件是初级粒子
|
||||||
|
const auto& firstParticle = spdt;
|
||||||
|
int boardId = firstParticle.board_id + 1;
|
||||||
|
int channelId = firstParticle.channel_id + 1;
|
||||||
|
if(firstParticle.eventId == eventId) continue;
|
||||||
|
eventId = firstParticle.eventId;
|
||||||
|
if (boardId >= 1 && boardId <= 8 && channelId >= 1 && channelId <= 4) {
|
||||||
|
SpectrumDataList.append(spdt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QVector<double> vx, vy;
|
||||||
|
int ncount = 0;
|
||||||
|
for(const auto &spdt : SpectrumDataList)
|
||||||
|
{
|
||||||
|
ncount++;
|
||||||
|
vx << spdt.timestamp;
|
||||||
|
vy << ncount;
|
||||||
|
}
|
||||||
|
|
||||||
|
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->SetAxisInitRange(QwtPlot::yLeft,0.0f, dmaxy);
|
||||||
|
_plot->SetAxisInitRange(QwtPlot::xBottom,0.0f, dmaxx);
|
||||||
|
_plot->replot();
|
||||||
|
_busy_indicator->Stop();
|
||||||
|
}, Qt::QueuedConnection);
|
||||||
|
};
|
||||||
|
|
||||||
|
QThread* load_thread = QThread::create(functionToRun);
|
||||||
|
load_thread->start();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CoincidenceEventTimeView::showEvent(QShowEvent *e)
|
||||||
|
{
|
||||||
|
Q_UNUSED(e);
|
||||||
|
if (_busy_indicator) {
|
||||||
|
_busy_indicator->setGeometry(this->rect());
|
||||||
|
this->update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CoincidenceEventTimeView::setupMenu()
|
||||||
|
{
|
||||||
|
this->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||||
|
connect(this, &CoincidenceEventTimeView::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, &CoincidenceEventTimeView::onActionPlotConfigure);
|
||||||
|
this->_menu->addSeparator();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CoincidenceEventTimeView::onActionPlotConfigure()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
37
src/CoincidenceEventTimeView/CoincidenceEventTimeView.h
Normal file
37
src/CoincidenceEventTimeView/CoincidenceEventTimeView.h
Normal file
|
|
@ -0,0 +1,37 @@
|
||||||
|
#ifndef COINCIDENCEEVENTTIMEVIEW_H
|
||||||
|
#define COINCIDENCEEVENTTIMEVIEW_H
|
||||||
|
|
||||||
|
#include "MeasureAnalysisView.h"
|
||||||
|
#include <QMenu>
|
||||||
|
class CustomQwtPlot;
|
||||||
|
class QwtPlotCurve;
|
||||||
|
class BusyIndicator;
|
||||||
|
|
||||||
|
class CoincidenceEventTimeView : public MeasureAnalysisView
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit CoincidenceEventTimeView(QWidget *parent = nullptr);
|
||||||
|
virtual ~CoincidenceEventTimeView();
|
||||||
|
virtual void InitViewWorkspace(const QString& project_name) override final;
|
||||||
|
virtual void SetAnalyzeDataFilename(const QMap<QString, QVariant>& data_files_set) override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void showEvent(QShowEvent* e) override final;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void loadAndProcess(); // 读取CSV,执行符合处理,绘制能谱折线图
|
||||||
|
void setupMenu();
|
||||||
|
private slots:
|
||||||
|
void onActionPlotConfigure();
|
||||||
|
private:
|
||||||
|
BusyIndicator* _busy_indicator = nullptr;
|
||||||
|
CustomQwtPlot* _plot = nullptr;
|
||||||
|
QwtPlotCurve* _curve = nullptr;
|
||||||
|
QStringList _data_filenames;
|
||||||
|
QMenu* _menu = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // COINCIDENCEEVENTTIMEVIEW_H
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -116,25 +116,25 @@ void ConformToTheEnergySpectrum::loadAndProcess()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// const uint64_t TIME_WINDOW_NS = 50;
|
// const uint64_t TIME_WINDOW_NS = 50;
|
||||||
// const int MIN_ORDER = 2;
|
// const int MIN_ORDER = 2;
|
||||||
// const int MAX_ORDER = 9;
|
// const int MAX_ORDER = 9;
|
||||||
// std::vector<CoincidenceEvent> coincidences = processCoincidence(rawData, TIME_WINDOW_NS, MIN_ORDER, MAX_ORDER);
|
// std::vector<CoincidenceEvent> coincidences = processCoincidence(rawData, TIME_WINDOW_NS, MIN_ORDER, MAX_ORDER);
|
||||||
|
|
||||||
// if (coincidences.empty()) {
|
// if (coincidences.empty()) {
|
||||||
// _busy_indicator->Stop();
|
// _busy_indicator->Stop();
|
||||||
// return;
|
// return;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// const int STEP = 1;
|
// const int STEP = 1;
|
||||||
// std::map<int, double> hist;
|
// std::map<int, double> hist;
|
||||||
|
|
||||||
// for (const auto& ev : coincidences) {
|
// for (const auto& ev : coincidences) {
|
||||||
// for (const auto& spdt : ev.events) {
|
// for (const auto& spdt : ev.events) {
|
||||||
// int idx = static_cast<int>(spdt.energy) / STEP;
|
// int idx = static_cast<int>(spdt.energy) / STEP;
|
||||||
// hist[idx] += 1.0;
|
// hist[idx] += 1.0;
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
const int STEP = 1;
|
const int STEP = 1;
|
||||||
std::map<int, double> hist;
|
std::map<int, double> hist;
|
||||||
|
|
|
||||||
|
|
@ -225,9 +225,9 @@ void EnergyCountPeakFitView::setupMenu()
|
||||||
this->_plot->ResetPlot();
|
this->_plot->ResetPlot();
|
||||||
});
|
});
|
||||||
this->_menu->addSeparator();
|
this->_menu->addSeparator();
|
||||||
QAction* action_set_curve_show = this->_menu->addAction(QStringLiteral(u"选择曲线"));
|
//QAction* action_set_curve_show = this->_menu->addAction(QStringLiteral(u"选择曲线"));
|
||||||
action_set_curve_show->setObjectName("curve_show_setting");
|
//action_set_curve_show->setObjectName("curve_show_setting");
|
||||||
connect(action_set_curve_show, &QAction::triggered, this, &EnergyCountPeakFitView::onActionCurveShowSetting);
|
//connect(action_set_curve_show, &QAction::triggered, this, &EnergyCountPeakFitView::onActionCurveShowSetting);
|
||||||
QAction* action_plot_config = this->_menu->addAction(QStringLiteral(u"图表配置"));
|
QAction* action_plot_config = this->_menu->addAction(QStringLiteral(u"图表配置"));
|
||||||
action_plot_config->setObjectName("plot_config");
|
action_plot_config->setObjectName("plot_config");
|
||||||
connect(action_plot_config, &QAction::triggered, this, &EnergyCountPeakFitView::onActionPlotConfigure);
|
connect(action_plot_config, &QAction::triggered, this, &EnergyCountPeakFitView::onActionPlotConfigure);
|
||||||
|
|
@ -235,8 +235,8 @@ void EnergyCountPeakFitView::setupMenu()
|
||||||
this->_menu->addSeparator();
|
this->_menu->addSeparator();
|
||||||
QAction* action_refit_rect = this->_menu->addAction(QStringLiteral(u"重新拟合当前区域"));
|
QAction* action_refit_rect = this->_menu->addAction(QStringLiteral(u"重新拟合当前区域"));
|
||||||
connect(action_refit_rect, &QAction::triggered, this, &EnergyCountPeakFitView::onActionRefitCurrentRect);
|
connect(action_refit_rect, &QAction::triggered, this, &EnergyCountPeakFitView::onActionRefitCurrentRect);
|
||||||
QAction* action_save_fit = this->_menu->addAction(QStringLiteral(u"保存当前拟合结果"));
|
//QAction* action_save_fit = this->_menu->addAction(QStringLiteral(u"保存当前拟合结果"));
|
||||||
connect(action_save_fit, &QAction::triggered, this, &EnergyCountPeakFitView::onActionSaveCurrentFit);
|
//connect(action_save_fit, &QAction::triggered, this, &EnergyCountPeakFitView::onActionSaveCurrentFit);
|
||||||
|
|
||||||
QAction* action_show_history = this->_menu->addAction(QStringLiteral(u"峰拟合结果"));
|
QAction* action_show_history = this->_menu->addAction(QStringLiteral(u"峰拟合结果"));
|
||||||
connect(action_show_history, &QAction::triggered, this, &EnergyCountPeakFitView::onActionShowFitHistory);
|
connect(action_show_history, &QAction::triggered, this, &EnergyCountPeakFitView::onActionShowFitHistory);
|
||||||
|
|
@ -244,8 +244,8 @@ void EnergyCountPeakFitView::setupMenu()
|
||||||
QAction* action_delete_hovered_rect = this->_menu->addAction(QStringLiteral(u"删除当前框选区域"));
|
QAction* action_delete_hovered_rect = this->_menu->addAction(QStringLiteral(u"删除当前框选区域"));
|
||||||
connect(action_delete_hovered_rect, &QAction::triggered, this, &EnergyCountPeakFitView::onActionDeleteHoveredRect);
|
connect(action_delete_hovered_rect, &QAction::triggered, this, &EnergyCountPeakFitView::onActionDeleteHoveredRect);
|
||||||
|
|
||||||
QAction* action_hint = this->_menu->addAction(QStringLiteral(u"框选提示:按住 Ctrl 键并拖动左键"));
|
//QAction* action_hint = this->_menu->addAction(QStringLiteral(u"框选提示:按住 Ctrl 键并拖动左键"));
|
||||||
action_hint->setEnabled(false);
|
//action_hint->setEnabled(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EnergyCountPeakFitView::loadDataFromFile(const QString& data_name, const QString& filename)
|
void EnergyCountPeakFitView::loadDataFromFile(const QString& data_name, const QString& filename)
|
||||||
|
|
@ -390,8 +390,8 @@ bool EnergyCountPeakFitView::eventFilter(QObject* watched, QEvent* event)
|
||||||
|
|
||||||
// 按下 Ctrl+左键 开始框选
|
// 按下 Ctrl+左键 开始框选
|
||||||
if (event->type() == QEvent::MouseButtonPress &&
|
if (event->type() == QEvent::MouseButtonPress &&
|
||||||
me->button() == Qt::LeftButton &&
|
me->button() == Qt::LeftButton /*&&*/
|
||||||
(me->modifiers() & Qt::ControlModifier)) {
|
/*(me->modifiers() & Qt::ControlModifier)*/) {
|
||||||
startSelection(me->pos());
|
startSelection(me->pos());
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -485,7 +485,7 @@ void EnergyCountPeakFitView::finishSelection()
|
||||||
|
|
||||||
if (roiX.size() >= 3) {
|
if (roiX.size() >= 3) {
|
||||||
QStringList algorithms;
|
QStringList algorithms;
|
||||||
algorithms << QStringLiteral(u"光子峰拟合算法");
|
algorithms << QStringLiteral(u"y=A*exp(-pow(x-P,2)/(2*pow(delt,2))) + H/(1+exp((x-P)/W)) + C");
|
||||||
bool ok = false;
|
bool ok = false;
|
||||||
QString selected = QInputDialog::getItem(this,
|
QString selected = QInputDialog::getItem(this,
|
||||||
QStringLiteral(u"选择拟合算法"),
|
QStringLiteral(u"选择拟合算法"),
|
||||||
|
|
@ -494,7 +494,7 @@ void EnergyCountPeakFitView::finishSelection()
|
||||||
0,
|
0,
|
||||||
false,
|
false,
|
||||||
&ok);
|
&ok);
|
||||||
if (ok && selected == QStringLiteral(u"光子峰拟合算法"))
|
if (ok && selected == QStringLiteral(u"y=A*exp(-pow(x-P,2)/(2*pow(delt,2))) + H/(1+exp((x-P)/W)) + C"))
|
||||||
{
|
{
|
||||||
arma::vec armaRoiX(roiX.size()), armaRoiY(roiY.size());
|
arma::vec armaRoiX(roiX.size()), armaRoiY(roiY.size());
|
||||||
for (int i = 0; i < roiX.size(); ++i) {
|
for (int i = 0; i < roiX.size(); ++i) {
|
||||||
|
|
|
||||||
|
|
@ -82,7 +82,8 @@ void PlotRectItem::draw(QPainter *painter,
|
||||||
painter->setRenderHint(QPainter::TextAntialiasing);
|
painter->setRenderHint(QPainter::TextAntialiasing);
|
||||||
|
|
||||||
// 构建文本内容
|
// 构建文本内容
|
||||||
QString text = QString("峰位: %1 keV\n"
|
QString text = QString(
|
||||||
|
"峰位: %1 keV\n"
|
||||||
"FWHM: %2\n"
|
"FWHM: %2\n"
|
||||||
"面积: %3\n"
|
"面积: %3\n"
|
||||||
"本底: %4")
|
"本底: %4")
|
||||||
|
|
@ -92,7 +93,7 @@ void PlotRectItem::draw(QPainter *painter,
|
||||||
.arg(m_baseline, 0, 'f', 2);
|
.arg(m_baseline, 0, 'f', 2);
|
||||||
|
|
||||||
// 计算文本位置:矩形右上角 + 偏移量
|
// 计算文本位置:矩形右上角 + 偏移量
|
||||||
QPoint textPos(x2 + 10, y2);
|
QPoint textPos(x2 + 20, y2 + 10);
|
||||||
|
|
||||||
// 绘制半透明背景框(增强可读性)
|
// 绘制半透明背景框(增强可读性)
|
||||||
QFont font = painter->font();
|
QFont font = painter->font();
|
||||||
|
|
|
||||||
|
|
@ -276,6 +276,24 @@ void MeasureAnalysisTreeView::onNodeDoubleClicked(const QModelIndex& index)
|
||||||
data_files_set[QStringLiteral(u"反符合粒子数据")] = file_name;
|
data_files_set[QStringLiteral(u"反符合粒子数据")] = file_name;
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
case AnalysisType::CoincidenceEventTimeView: {
|
||||||
|
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;
|
||||||
|
case AnalysisType::NuclideAnalysisView: {
|
||||||
|
MeasureAnalysisProjectModel* project_model = _model->GetProjectModel(project_name);
|
||||||
|
if (project_model) {
|
||||||
|
auto all_ch_energy_count_file_name = project_model->GetAllChannelEnergyTotalCountDataFilename();
|
||||||
|
if (!all_ch_energy_count_file_name.isEmpty()) {
|
||||||
|
data_files_set[QStringLiteral(u"核素分析")] = all_ch_energy_count_file_name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,8 @@
|
||||||
#include "TwoDSpectralCompliance.h"
|
#include "TwoDSpectralCompliance.h"
|
||||||
#include "ConformToTheEnergySpectrum.h"
|
#include "ConformToTheEnergySpectrum.h"
|
||||||
#include "AntiConformEnergySpectrumView.h"
|
#include "AntiConformEnergySpectrumView.h"
|
||||||
|
#include "CoincidenceEventTimeView.h"
|
||||||
|
#include "NuclideAnalysisView.h"
|
||||||
#include <QMap>
|
#include <QMap>
|
||||||
|
|
||||||
MeasureAnalysisView* MeasureAnalysisView::NewAnalyzeView(AnalysisType view_type)
|
MeasureAnalysisView* MeasureAnalysisView::NewAnalyzeView(AnalysisType view_type)
|
||||||
|
|
@ -82,8 +84,8 @@ MeasureAnalysisView* MeasureAnalysisView::NewAnalyzeView(AnalysisType view_type)
|
||||||
new_view->setDeleteOnClose(false);
|
new_view->setDeleteOnClose(false);
|
||||||
} break;
|
} break;
|
||||||
case AnalysisType::NuclideAnalysisView: {
|
case AnalysisType::NuclideAnalysisView: {
|
||||||
// new_view = new MeasureAnalysisDataTableView;
|
new_view = new NuclideAnalysisView;
|
||||||
// new_view->setDeleteOnClose(false);
|
new_view->setDeleteOnClose(false);
|
||||||
} break;
|
} break;
|
||||||
case AnalysisType::ParticleInTimeView: {
|
case AnalysisType::ParticleInTimeView: {
|
||||||
new_view = new ParticleInjectTimeAnalysisView;
|
new_view = new ParticleInjectTimeAnalysisView;
|
||||||
|
|
@ -94,8 +96,8 @@ MeasureAnalysisView* MeasureAnalysisView::NewAnalyzeView(AnalysisType view_type)
|
||||||
new_view->setDeleteOnClose(false);
|
new_view->setDeleteOnClose(false);
|
||||||
} break;
|
} break;
|
||||||
case AnalysisType::CoincidenceEventTimeView: {
|
case AnalysisType::CoincidenceEventTimeView: {
|
||||||
// new_view = new MeasureAnalysisParticleCountPlotView;
|
new_view = new CoincidenceEventTimeView;
|
||||||
// new_view->setDeleteOnClose(false);
|
new_view->setDeleteOnClose(false);
|
||||||
} break;
|
} break;
|
||||||
case AnalysisType::CoincidenceParticleEnergySpectrumView: {
|
case AnalysisType::CoincidenceParticleEnergySpectrumView: {
|
||||||
new_view = new ConformToTheEnergySpectrum;
|
new_view = new ConformToTheEnergySpectrum;
|
||||||
|
|
@ -105,6 +107,7 @@ MeasureAnalysisView* MeasureAnalysisView::NewAnalyzeView(AnalysisType view_type)
|
||||||
new_view = new AntiConformEnergySpectrumView;
|
new_view = new AntiConformEnergySpectrumView;
|
||||||
new_view->setDeleteOnClose(false);
|
new_view->setDeleteOnClose(false);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
138
src/NuclideAnalysisView/NuclideAnalysisView.cpp
Normal file
138
src/NuclideAnalysisView/NuclideAnalysisView.cpp
Normal file
|
|
@ -0,0 +1,138 @@
|
||||||
|
#include "NuclideAnalysisView.h"
|
||||||
|
#include "CustomQwtPlot.h"
|
||||||
|
#include "csv.h"
|
||||||
|
#include <GlobalDefine.h>
|
||||||
|
#include <QFileInfo>
|
||||||
|
#include <QwtPlotCurve>
|
||||||
|
#include <QHBoxLayout>
|
||||||
|
#include "MeasureAnalysisProjectModel.h"
|
||||||
|
#include <QDir>
|
||||||
|
#include <QwtPlotCanvas>
|
||||||
|
#include <QwtText>
|
||||||
|
#include <QPen>
|
||||||
|
NuclideAnalysisView::NuclideAnalysisView(QWidget* parent)
|
||||||
|
: MeasureAnalysisView { parent }
|
||||||
|
{
|
||||||
|
this->setViewType(PlotFrame);
|
||||||
|
QHBoxLayout* layout = new QHBoxLayout(this);
|
||||||
|
this->_plot = new CustomQwtPlot(this);
|
||||||
|
layout->addWidget(this->_plot);
|
||||||
|
setupPlot();
|
||||||
|
this->_menu = new QMenu(this);
|
||||||
|
setupMenu();
|
||||||
|
}
|
||||||
|
|
||||||
|
NuclideAnalysisView::~NuclideAnalysisView()
|
||||||
|
{
|
||||||
|
LOG_DEBUG(QStringLiteral(u"%1析构.").arg(this->GetViewName()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void NuclideAnalysisView::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;
|
||||||
|
QDir project_dir(project_model->GetProjectDir());
|
||||||
|
_workspace = project_dir.filePath(this->GetViewName());
|
||||||
|
if (!QDir(_workspace).exists())
|
||||||
|
project_dir.mkpath(_workspace);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NuclideAnalysisView::SetAnalyzeDataFilename(const QMap<QString, QVariant>& data_files_set)
|
||||||
|
{
|
||||||
|
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()) {
|
||||||
|
loadDataFromFile(data_name, data_filename);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NuclideAnalysisView::setupPlot()
|
||||||
|
{
|
||||||
|
_plot->setCanvasBackground(Qt::white);
|
||||||
|
QwtPlotCanvas* canvas = qobject_cast<QwtPlotCanvas*>(_plot->canvas());
|
||||||
|
canvas->setFrameStyle(QFrame::NoFrame);
|
||||||
|
QFont font = this->font();
|
||||||
|
font.setBold(false);
|
||||||
|
QwtText energy_label = QStringLiteral(u"能量(KeV)");
|
||||||
|
energy_label.setFont(font);
|
||||||
|
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);
|
||||||
|
_plot->SetAxisDragScale(QwtPlot::xBottom, true);
|
||||||
|
// 启用鼠标追踪
|
||||||
|
_plot->canvas()->setMouseTracking(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NuclideAnalysisView::setupMenu()
|
||||||
|
{
|
||||||
|
this->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||||
|
connect(this, &NuclideAnalysisView::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, &NuclideAnalysisView::onActionPlotConfigure);
|
||||||
|
this->_menu->addSeparator();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void NuclideAnalysisView::loadDataFromFile(const QString& data_name, const QString& filename)
|
||||||
|
{
|
||||||
|
// 加载新数据前清空旧数据
|
||||||
|
_plot->replot();
|
||||||
|
|
||||||
|
std::string address_str = QString(QStringLiteral(u"能量(KeV)")).toStdString();
|
||||||
|
std::string count_str = QString(QStringLiteral(u"计数")).toStdString();
|
||||||
|
io::CSVReader<
|
||||||
|
2,
|
||||||
|
io::trim_chars<' ', '\t'>,
|
||||||
|
io::double_quote_escape<',', '"'>,
|
||||||
|
io::throw_on_overflow,
|
||||||
|
io::empty_line_comment>
|
||||||
|
reader(QStrToSysPath(filename));
|
||||||
|
reader.read_header(io::ignore_extra_column, address_str, count_str);
|
||||||
|
|
||||||
|
double energy;
|
||||||
|
unsigned long long energy_count;
|
||||||
|
QVector<double> x, y;
|
||||||
|
while (reader.read_row(energy, energy_count)) {
|
||||||
|
x.push_back(energy);
|
||||||
|
y.push_back(energy_count);
|
||||||
|
if(_x_max < energy)
|
||||||
|
_x_max = energy;
|
||||||
|
if(_y_max < energy_count)
|
||||||
|
_y_max = energy_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
_plot->SetAxisInitRange(QwtPlot::xBottom,0.0f,_x_max);
|
||||||
|
_plot->SetAxisInitRange(QwtPlot::yLeft,0.0f,_y_max);
|
||||||
|
|
||||||
|
// 绘制原始数据曲线
|
||||||
|
QwtPlotCurve* curve = new QwtPlotCurve(QStringLiteral(u"原始数据"));
|
||||||
|
curve->setPen(QPen(Qt::gray, 2)); // 原始数据统一灰色
|
||||||
|
curve->setSamples(x, y);
|
||||||
|
_plot->AddCurve(curve,false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NuclideAnalysisView::onActionPlotConfigure()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
33
src/NuclideAnalysisView/NuclideAnalysisView.h
Normal file
33
src/NuclideAnalysisView/NuclideAnalysisView.h
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
#ifndef NUCLIDEANALYSISVIEW_H
|
||||||
|
#define NUCLIDEANALYSISVIEW_H
|
||||||
|
#include <QObject>
|
||||||
|
#include <QWidget>
|
||||||
|
#include <MeasureAnalysisView.h>
|
||||||
|
#include <QwtPlotCurve>
|
||||||
|
#include <QMenu>
|
||||||
|
class CustomQwtPlot;
|
||||||
|
class NuclideAnalysisView : public MeasureAnalysisView
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
NuclideAnalysisView(QWidget *parent = nullptr);
|
||||||
|
virtual ~NuclideAnalysisView();
|
||||||
|
virtual void InitViewWorkspace(const QString& project_name) override final;
|
||||||
|
virtual void SetAnalyzeDataFilename(const QMap<QString, QVariant>& data_files_set);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void setupPlot();
|
||||||
|
void setupMenu();
|
||||||
|
void loadDataFromFile(const QString &data_name, const QString& filename);
|
||||||
|
private slots:
|
||||||
|
void onActionPlotConfigure();
|
||||||
|
|
||||||
|
private:
|
||||||
|
CustomQwtPlot* _plot = nullptr;
|
||||||
|
QString _workspace;
|
||||||
|
QMenu* _menu = nullptr;
|
||||||
|
|
||||||
|
int _x_max = 0;
|
||||||
|
int _y_max = 0;
|
||||||
|
};
|
||||||
|
#endif // NUCLIDEANALYSISVIEW_H
|
||||||
|
|
@ -17,7 +17,7 @@ void ButtonDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option
|
||||||
if (index.column() == 7) {
|
if (index.column() == 7) {
|
||||||
QStyleOptionButton button;
|
QStyleOptionButton button;
|
||||||
button.rect = option.rect;
|
button.rect = option.rect;
|
||||||
button.text = "核素发射射线信息";
|
button.text = QStringLiteral(u"核素发射射线信息");
|
||||||
button.state = QStyle::State_Enabled;
|
button.state = QStyle::State_Enabled;
|
||||||
if (option.state & QStyle::State_MouseOver)
|
if (option.state & QStyle::State_MouseOver)
|
||||||
button.state |= QStyle::State_MouseOver;
|
button.state |= QStyle::State_MouseOver;
|
||||||
|
|
@ -63,8 +63,9 @@ NuclideLibManage::NuclideLibManage(QWidget *parent) :
|
||||||
ui->tableView->setAlternatingRowColors(true);
|
ui->tableView->setAlternatingRowColors(true);
|
||||||
ui->tableView->setSelectionBehavior(QAbstractItemView::SelectRows);
|
ui->tableView->setSelectionBehavior(QAbstractItemView::SelectRows);
|
||||||
ui->tableView->setFocusPolicy(Qt::NoFocus);
|
ui->tableView->setFocusPolicy(Qt::NoFocus);
|
||||||
|
ui->tableView->verticalHeader()->setVisible(false);
|
||||||
|
|
||||||
QString dbPath = QCoreApplication::applicationDirPath() + "/nuclideLib.db"; // 绝对路径(推荐)
|
QString dbPath = QCoreApplication::applicationDirPath() + "/nuclideLib.db";
|
||||||
qDebug()<<dbPath;
|
qDebug()<<dbPath;
|
||||||
bool dbOpened = SqliteManager::instance().openDatabase(dbPath);
|
bool dbOpened = SqliteManager::instance().openDatabase(dbPath);
|
||||||
if (!dbOpened) {
|
if (!dbOpened) {
|
||||||
|
|
@ -98,9 +99,9 @@ void NuclideLibManage::loadNuclideData()
|
||||||
item << rec["ID"].toString()
|
item << rec["ID"].toString()
|
||||||
<< rec["NUCLIDE_NAME"].toString()
|
<< rec["NUCLIDE_NAME"].toString()
|
||||||
<< rec["HALF_LIFE"].toString()
|
<< rec["HALF_LIFE"].toString()
|
||||||
<< rec["HALF_LIFE_UNCERTAINTY"].toString() // 对应新字段名
|
<< rec["HALF_LIFE_UNCERTAINTY"].toString()
|
||||||
<< rec["PARENT_NUCLIDE_NAME"].toString() // 对应新字段名
|
<< rec["PARENT_NUCLIDE_NAME"].toString()
|
||||||
<< rec["CHILD_NUCLIDE_NAME"].toString(); // 对应新字段名
|
<< rec["CHILD_NUCLIDE_NAME"].toString();
|
||||||
m_listNuclide.append(item);
|
m_listNuclide.append(item);
|
||||||
|
|
||||||
// 插入模型行(界面显示逻辑不变)
|
// 插入模型行(界面显示逻辑不变)
|
||||||
|
|
@ -158,10 +159,10 @@ void NuclideLibManage::on_pushButton_add_clicked()
|
||||||
|
|
||||||
qint64 newId = SqliteManager::instance().insertRow("nuclideLib", fieldValues);
|
qint64 newId = SqliteManager::instance().insertRow("nuclideLib", fieldValues);
|
||||||
if (newId > 0) {
|
if (newId > 0) {
|
||||||
QMessageBox::information(this, "成功", "核素添加成功!");
|
QMessageBox::information(this, QStringLiteral(u"成功"), QStringLiteral(u"核素添加成功!"));
|
||||||
loadNuclideData();
|
loadNuclideData();
|
||||||
} else {
|
} else {
|
||||||
QMessageBox::warning(this, "失败", "添加失败:" + SqliteManager::instance().lastError());
|
QMessageBox::warning(this, QStringLiteral(u"失败"), QStringLiteral(u"添加失败:") + SqliteManager::instance().lastError());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -170,7 +171,7 @@ void NuclideLibManage::on_pushButton_edit_clicked()
|
||||||
{
|
{
|
||||||
QModelIndexList selected = ui->tableView->selectionModel()->selectedRows();
|
QModelIndexList selected = ui->tableView->selectionModel()->selectedRows();
|
||||||
if (selected.isEmpty()) {
|
if (selected.isEmpty()) {
|
||||||
QMessageBox::information(this, "提示", "请先选择要修改的核素行!");
|
QMessageBox::information(this, QStringLiteral(u"提示"), QStringLiteral(u"请先选择要修改的核素行!"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -199,12 +200,12 @@ void NuclideLibManage::on_pushButton_edit_clicked()
|
||||||
);
|
);
|
||||||
|
|
||||||
if (affectedRows > 0) {
|
if (affectedRows > 0) {
|
||||||
QMessageBox::information(this, "成功", "核素修改成功!");
|
QMessageBox::information(this, QStringLiteral(u"成功"), QStringLiteral(u"核素修改成功!"));
|
||||||
loadNuclideData();
|
loadNuclideData();
|
||||||
} else if (affectedRows == 0) {
|
} else if (affectedRows == 0) {
|
||||||
QMessageBox::information(this, "提示", "未修改任何数据!");
|
QMessageBox::information(this, QStringLiteral(u"提示"), QStringLiteral(u"未修改任何数据!"));
|
||||||
} else {
|
} else {
|
||||||
QMessageBox::warning(this, "失败", "修改失败:" + SqliteManager::instance().lastError());
|
QMessageBox::warning(this, QStringLiteral(u"失败"), QStringLiteral(u"修改失败:") + SqliteManager::instance().lastError());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -213,24 +214,24 @@ void NuclideLibManage::on_pushButton_del_clicked()
|
||||||
{
|
{
|
||||||
QModelIndexList selected = ui->tableView->selectionModel()->selectedRows();
|
QModelIndexList selected = ui->tableView->selectionModel()->selectedRows();
|
||||||
if (selected.isEmpty()) {
|
if (selected.isEmpty()) {
|
||||||
QMessageBox::information(this, "提示", "请先选择要删除的核素行!");
|
QMessageBox::information(this, QStringLiteral(u"提示"), QStringLiteral(u"请先选择要删除的核素行!"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int row = selected.first().row();
|
int row = selected.first().row();
|
||||||
QString id = m_model->index(row, 0).data().toString();
|
QString id = m_model->index(row, 0).data().toString();
|
||||||
|
|
||||||
QMessageBox box(QMessageBox::Question, "提示", "确定删除该核素吗?",
|
QMessageBox box(QMessageBox::Question, QStringLiteral(u"提示"), QStringLiteral(u"确定删除该核素吗?"),
|
||||||
QMessageBox::Yes | QMessageBox::No, this);
|
QMessageBox::Yes | QMessageBox::No, this);
|
||||||
box.button(QMessageBox::Yes)->setText("确认");
|
box.button(QMessageBox::Yes)->setText(QStringLiteral(u"确认"));
|
||||||
box.button(QMessageBox::No)->setText("取消");
|
box.button(QMessageBox::No)->setText(QStringLiteral(u"取消"));
|
||||||
if (box.exec() != QMessageBox::Yes) return;
|
if (box.exec() != QMessageBox::Yes) return;
|
||||||
|
|
||||||
bool ok = SqliteManager::instance().deleteRow("nuclideLib", "ID = ?", {id});
|
bool ok = SqliteManager::instance().deleteRow("nuclideLib", "ID = ?", {id});
|
||||||
if (ok) {
|
if (ok) {
|
||||||
loadNuclideData();
|
loadNuclideData();
|
||||||
} else {
|
} else {
|
||||||
QMessageBox::warning(this, "错误", "删除失败:" + SqliteManager::instance().lastError());
|
QMessageBox::warning(this, QStringLiteral(u"错误"), QStringLiteral(u"删除失败:") + SqliteManager::instance().lastError());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,40 +23,40 @@ NuclideRayDialog::NuclideRayDialog(bool isEdit, const QStringList& rayData, QWid
|
||||||
|
|
||||||
void NuclideRayDialog::initUI()
|
void NuclideRayDialog::initUI()
|
||||||
{
|
{
|
||||||
setWindowTitle(m_isEdit ? "编辑射线信息" : "添加射线信息");
|
setWindowTitle(m_isEdit ? QStringLiteral(u"编辑射线信息") : QStringLiteral(u"添加射线信息"));
|
||||||
setFixedSize(450, 300);
|
setFixedSize(450, 300);
|
||||||
|
|
||||||
QFormLayout *formLayout = new QFormLayout(this);
|
QFormLayout *formLayout = new QFormLayout(this);
|
||||||
|
|
||||||
// 射线类型下拉框(常用核素射线类型)
|
// 射线类型下拉框(常用核素射线类型)
|
||||||
m_cmbRayType = new QComboBox(this);
|
m_cmbRayType = new QComboBox(this);
|
||||||
m_cmbRayType->addItems({"γ", "β⁻", "β⁺", "α", "X射线", "中子", "电子俘获"});
|
m_cmbRayType->addItems({QStringLiteral(u"γ"), QStringLiteral(u"β⁻"), QStringLiteral(u"β⁺"), QStringLiteral(u"α"), QStringLiteral(u"X射线"), QStringLiteral(u"中子"), QStringLiteral(u"电子俘获")});
|
||||||
formLayout->addRow("射线类型", m_cmbRayType);
|
formLayout->addRow(QStringLiteral(u"射线类型"), m_cmbRayType);
|
||||||
|
|
||||||
m_leRayMev = new QLineEdit(this);
|
m_leRayMev = new QLineEdit(this);
|
||||||
m_leRayMev->setPlaceholderText("例如:1.332 MeV");
|
m_leRayMev->setPlaceholderText(QStringLiteral(u"例如:1.332 MeV"));
|
||||||
formLayout->addRow("射线能量", m_leRayMev);
|
formLayout->addRow(QStringLiteral(u"射线能量"), m_leRayMev);
|
||||||
|
|
||||||
m_leRayMevUnc = new QLineEdit(this);
|
m_leRayMevUnc = new QLineEdit(this);
|
||||||
m_leRayMevUnc->setPlaceholderText("例如:0.001 MeV");
|
m_leRayMevUnc->setPlaceholderText(QStringLiteral(u"例如:0.001 MeV"));
|
||||||
formLayout->addRow("能量不确定度", m_leRayMevUnc);
|
formLayout->addRow(QStringLiteral(u"能量不确定度"), m_leRayMevUnc);
|
||||||
|
|
||||||
m_leBranchRatio = new QLineEdit(this);
|
m_leBranchRatio = new QLineEdit(this);
|
||||||
m_leBranchRatio->setPlaceholderText("例如: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("例如:0.0001");
|
m_leBranchRatioUnc->setPlaceholderText(QStringLiteral(u"例如:0.0001"));
|
||||||
formLayout->addRow("分支比不确定度", m_leBranchRatioUnc);
|
formLayout->addRow(QStringLiteral(u"分支比不确定度"), m_leBranchRatioUnc);
|
||||||
|
|
||||||
// 主射线标识下拉框
|
// 主射线标识下拉框
|
||||||
m_cmbMainRayIdent = new QComboBox(this);
|
m_cmbMainRayIdent = new QComboBox(this);
|
||||||
m_cmbMainRayIdent->addItems({"是", "否"});
|
m_cmbMainRayIdent->addItems({QStringLiteral(u"是"), QStringLiteral(u"否")});
|
||||||
formLayout->addRow("是否为主射线", m_cmbMainRayIdent);
|
formLayout->addRow(QStringLiteral(u"是否为主射线"), m_cmbMainRayIdent);
|
||||||
|
|
||||||
m_leJiahePeak = new QLineEdit(this);
|
m_leJiahePeak = new QLineEdit(this);
|
||||||
m_leJiahePeak->setPlaceholderText("无则留空");
|
m_leJiahePeak->setPlaceholderText(QStringLiteral(u"无则留空"));
|
||||||
formLayout->addRow("加和峰", m_leJiahePeak);
|
formLayout->addRow(QStringLiteral(u"加和峰"), m_leJiahePeak);
|
||||||
|
|
||||||
// 按钮盒
|
// 按钮盒
|
||||||
QDialogButtonBox *btnBox = new QDialogButtonBox(
|
QDialogButtonBox *btnBox = new QDialogButtonBox(
|
||||||
|
|
@ -77,15 +77,15 @@ bool NuclideRayDialog::validateInput()
|
||||||
{
|
{
|
||||||
// 必填项校验
|
// 必填项校验
|
||||||
if (m_leRayMev->text().trimmed().isEmpty()) {
|
if (m_leRayMev->text().trimmed().isEmpty()) {
|
||||||
QMessageBox::warning(this, "输入错误", "射线能量不能为空!");
|
QMessageBox::warning(this, QStringLiteral(u"输入错误"), QStringLiteral(u"射线能量不能为空!"));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (m_leRayMevUnc->text().trimmed().isEmpty()) {
|
if (m_leRayMevUnc->text().trimmed().isEmpty()) {
|
||||||
QMessageBox::warning(this, "输入错误", "能量不确定度不能为空!");
|
QMessageBox::warning(this, QStringLiteral(u"输入错误"), QStringLiteral(u"能量不确定度不能为空!"));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (m_leBranchRatioUnc->text().trimmed().isEmpty()) {
|
if (m_leBranchRatioUnc->text().trimmed().isEmpty()) {
|
||||||
QMessageBox::warning(this, "输入错误", "分支比不确定度不能为空!");
|
QMessageBox::warning(this, QStringLiteral(u"输入错误"), QStringLiteral(u"分支比不确定度不能为空!"));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -95,21 +95,21 @@ bool NuclideRayDialog::validateInput()
|
||||||
QString mevText = m_leRayMev->text().trimmed().replace(QRegExp("[^0-9.]"), "");
|
QString mevText = m_leRayMev->text().trimmed().replace(QRegExp("[^0-9.]"), "");
|
||||||
mevText.toDouble(&ok);
|
mevText.toDouble(&ok);
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
QMessageBox::warning(this, "输入错误", "射线能量必须为有效数字!");
|
QMessageBox::warning(this, QStringLiteral(u"输入错误"), QStringLiteral(u"射线能量必须为有效数字!"));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString mevUncText = m_leRayMevUnc->text().trimmed().replace(QRegExp("[^0-9.]"), "");
|
QString mevUncText = m_leRayMevUnc->text().trimmed().replace(QRegExp("[^0-9.]"), "");
|
||||||
mevUncText.toDouble(&ok);
|
mevUncText.toDouble(&ok);
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
QMessageBox::warning(this, "输入错误", "能量不确定度必须为有效数字!");
|
QMessageBox::warning(this, QStringLiteral(u"输入错误"), QStringLiteral(u"能量不确定度必须为有效数字!"));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString ratioUncText = m_leBranchRatioUnc->text().trimmed().replace(QRegExp("[^0-9.]"), "");
|
QString ratioUncText = m_leBranchRatioUnc->text().trimmed().replace(QRegExp("[^0-9.]"), "");
|
||||||
ratioUncText.toDouble(&ok);
|
ratioUncText.toDouble(&ok);
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
QMessageBox::warning(this, "输入错误", "分支比不确定度必须为有效数字!");
|
QMessageBox::warning(this, QStringLiteral(u"输入错误"), QStringLiteral(u"分支比不确定度必须为有效数字!"));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ void RayButtonDelegate::paint(QPainter *painter, const QStyleOptionViewItem &opt
|
||||||
// 绘制编辑按钮
|
// 绘制编辑按钮
|
||||||
QStyleOptionButton editBtn;
|
QStyleOptionButton editBtn;
|
||||||
editBtn.rect = QRect(option.rect.x(), option.rect.y() + 2, 60, option.rect.height() - 4);
|
editBtn.rect = QRect(option.rect.x(), option.rect.y() + 2, 60, option.rect.height() - 4);
|
||||||
editBtn.text = "编辑";
|
editBtn.text = QStringLiteral(u"编辑");
|
||||||
editBtn.state = QStyle::State_Enabled;
|
editBtn.state = QStyle::State_Enabled;
|
||||||
if (option.state & QStyle::State_MouseOver)
|
if (option.state & QStyle::State_MouseOver)
|
||||||
editBtn.state |= QStyle::State_MouseOver;
|
editBtn.state |= QStyle::State_MouseOver;
|
||||||
|
|
@ -17,7 +17,7 @@ void RayButtonDelegate::paint(QPainter *painter, const QStyleOptionViewItem &opt
|
||||||
// 绘制删除按钮
|
// 绘制删除按钮
|
||||||
QStyleOptionButton delBtn;
|
QStyleOptionButton delBtn;
|
||||||
delBtn.rect = QRect(option.rect.x() + 70, option.rect.y() + 2, 60, option.rect.height() - 4);
|
delBtn.rect = QRect(option.rect.x() + 70, option.rect.y() + 2, 60, option.rect.height() - 4);
|
||||||
delBtn.text = "删除";
|
delBtn.text = QStringLiteral(u"删除");
|
||||||
delBtn.state = QStyle::State_Enabled;
|
delBtn.state = QStyle::State_Enabled;
|
||||||
if (option.state & QStyle::State_MouseOver)
|
if (option.state & QStyle::State_MouseOver)
|
||||||
delBtn.state |= QStyle::State_MouseOver;
|
delBtn.state |= QStyle::State_MouseOver;
|
||||||
|
|
@ -54,26 +54,27 @@ NuclideRayListDialog::NuclideRayListDialog(const QString& nuclideId, const QStri
|
||||||
|
|
||||||
void NuclideRayListDialog::initUI()
|
void NuclideRayListDialog::initUI()
|
||||||
{
|
{
|
||||||
setWindowTitle(QString("%1 - 射线信息管理").arg(m_nuclideName));
|
setWindowTitle(QStringLiteral(u"%1 - 射线信息管理").arg(m_nuclideName));
|
||||||
setFixedSize(900, 500);
|
setFixedSize(1100, 500);
|
||||||
|
|
||||||
QVBoxLayout *mainLayout = new QVBoxLayout(this);
|
QVBoxLayout *mainLayout = new QVBoxLayout(this);
|
||||||
|
|
||||||
// 添加按钮
|
// 添加按钮
|
||||||
QPushButton *btnAdd = new QPushButton("添加射线", this);
|
QPushButton *btnAdd = new QPushButton(QStringLiteral(u"添加射线"), this);
|
||||||
connect(btnAdd, &QPushButton::clicked, this, &NuclideRayListDialog::onAddRayClicked);
|
connect(btnAdd, &QPushButton::clicked, this, &NuclideRayListDialog::onAddRayClicked);
|
||||||
mainLayout->addWidget(btnAdd, 0, Qt::AlignRight);
|
mainLayout->addWidget(btnAdd, 0, Qt::AlignRight);
|
||||||
|
|
||||||
// 射线列表
|
// 射线列表
|
||||||
m_model = new QStandardItemModel(0, 9, this);
|
m_model = new QStandardItemModel(0, 9, this);
|
||||||
m_model->setHorizontalHeaderLabels({
|
m_model->setHorizontalHeaderLabels({
|
||||||
"ID", "射线类型", "能量(MeV)", "能量不确定度", "分支比",
|
QStringLiteral(u"ID"), QStringLiteral(u"射线类型"), QStringLiteral(u"能量(MeV)"), QStringLiteral(u"能量不确定度"), QStringLiteral(u"分支比"),
|
||||||
"分支比不确定度", "主射线", "加和峰", "操作"
|
QStringLiteral(u"分支比不确定度"), QStringLiteral(u"主射线"), QStringLiteral(u"加和峰"), QStringLiteral(u"操作")
|
||||||
});
|
});
|
||||||
|
|
||||||
QTableView *tableView = new QTableView(this);
|
QTableView *tableView = new QTableView(this);
|
||||||
tableView->setModel(m_model);
|
tableView->setModel(m_model);
|
||||||
tableView->setColumnHidden(0, true); // 隐藏ID列
|
tableView->verticalHeader()->setVisible(false);
|
||||||
|
tableView->setColumnWidth(0, 80); // ID
|
||||||
tableView->setColumnWidth(1, 80); // 射线类型
|
tableView->setColumnWidth(1, 80); // 射线类型
|
||||||
tableView->setColumnWidth(2, 120); // 能量
|
tableView->setColumnWidth(2, 120); // 能量
|
||||||
tableView->setColumnWidth(3, 120); // 能量不确定度
|
tableView->setColumnWidth(3, 120); // 能量不确定度
|
||||||
|
|
@ -97,7 +98,7 @@ void NuclideRayListDialog::initUI()
|
||||||
mainLayout->addWidget(tableView);
|
mainLayout->addWidget(tableView);
|
||||||
|
|
||||||
// 关闭按钮
|
// 关闭按钮
|
||||||
QPushButton *btnClose = new QPushButton("关闭", this);
|
QPushButton *btnClose = new QPushButton(QStringLiteral(u"关闭"), this);
|
||||||
connect(btnClose, &QPushButton::clicked, this, &QDialog::accept);
|
connect(btnClose, &QPushButton::clicked, this, &QDialog::accept);
|
||||||
mainLayout->addWidget(btnClose, 0, Qt::AlignRight);
|
mainLayout->addWidget(btnClose, 0, Qt::AlignRight);
|
||||||
}
|
}
|
||||||
|
|
@ -181,10 +182,10 @@ void NuclideRayListDialog::onAddRayClicked()
|
||||||
|
|
||||||
qint64 newId = SqliteManager::instance().insertRow("nuclideRayInfo", fieldValues);
|
qint64 newId = SqliteManager::instance().insertRow("nuclideRayInfo", fieldValues);
|
||||||
if (newId > 0) {
|
if (newId > 0) {
|
||||||
QMessageBox::information(this, "成功", "射线信息添加成功!");
|
QMessageBox::information(this, QStringLiteral(u"成功"), QStringLiteral(u"射线信息添加成功!"));
|
||||||
loadRayData(); // 刷新列表
|
loadRayData(); // 刷新列表
|
||||||
} else {
|
} else {
|
||||||
QMessageBox::warning(this, "失败", "添加失败:" + SqliteManager::instance().lastError());
|
QMessageBox::warning(this, QStringLiteral(u"失败"), QStringLiteral(u"添加失败:") + SqliteManager::instance().lastError());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -218,12 +219,12 @@ void NuclideRayListDialog::onEditRayClicked(const QModelIndex &index)
|
||||||
);
|
);
|
||||||
|
|
||||||
if (affectedRows > 0) {
|
if (affectedRows > 0) {
|
||||||
QMessageBox::information(this, "成功", "射线信息修改成功!");
|
QMessageBox::information(this, QStringLiteral(u"成功"), QStringLiteral(u"射线信息修改成功!"));
|
||||||
loadRayData();
|
loadRayData();
|
||||||
} else if (affectedRows == 0) {
|
} else if (affectedRows == 0) {
|
||||||
QMessageBox::information(this, "提示", "未修改任何数据!");
|
QMessageBox::information(this, QStringLiteral(u"提示"), QStringLiteral(u"未修改任何数据!"));
|
||||||
} else {
|
} else {
|
||||||
QMessageBox::warning(this, "失败", "修改失败:" + SqliteManager::instance().lastError());
|
QMessageBox::warning(this, QStringLiteral(u"失败"), QStringLiteral(u"修改失败:") + SqliteManager::instance().lastError());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -233,16 +234,16 @@ void NuclideRayListDialog::onDeleteRayClicked(const QModelIndex &index)
|
||||||
int row = index.row();
|
int row = index.row();
|
||||||
QString id = m_model->index(row, 0).data().toString();
|
QString id = m_model->index(row, 0).data().toString();
|
||||||
|
|
||||||
QMessageBox box(QMessageBox::Question, "提示", "确定删除该射线信息吗?",
|
QMessageBox box(QMessageBox::Question, QStringLiteral(u"提示"), QStringLiteral(u"确定删除该射线信息吗?"),
|
||||||
QMessageBox::Yes | QMessageBox::No, this);
|
QMessageBox::Yes | QMessageBox::No, this);
|
||||||
box.button(QMessageBox::Yes)->setText("确认");
|
box.button(QMessageBox::Yes)->setText(QStringLiteral(u"确认"));
|
||||||
box.button(QMessageBox::No)->setText("取消");
|
box.button(QMessageBox::No)->setText(QStringLiteral(u"取消"));
|
||||||
if (box.exec() != QMessageBox::Yes) return;
|
if (box.exec() != QMessageBox::Yes) return;
|
||||||
|
|
||||||
bool ok = SqliteManager::instance().deleteRow("nuclideRayInfo", "ID = ?", {id});
|
bool ok = SqliteManager::instance().deleteRow("nuclideRayInfo", "ID = ?", {id});
|
||||||
if (ok) {
|
if (ok) {
|
||||||
loadRayData();
|
loadRayData();
|
||||||
} else {
|
} else {
|
||||||
QMessageBox::warning(this, "错误", "删除失败:" + SqliteManager::instance().lastError());
|
QMessageBox::warning(this, QStringLiteral(u"错误"), QStringLiteral(u"删除失败:") + SqliteManager::instance().lastError());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
15
src/src.pro
15
src/src.pro
|
|
@ -38,7 +38,10 @@ INCLUDEPATH += \
|
||||||
$${PWD}/2DSpectralCompliance \
|
$${PWD}/2DSpectralCompliance \
|
||||||
$${PWD}/ConformToTheEnergySpectrum \
|
$${PWD}/ConformToTheEnergySpectrum \
|
||||||
$${PWD}/NuclideLib \
|
$${PWD}/NuclideLib \
|
||||||
$${PWD}/AntiConformEnergySpectrumView
|
$${PWD}/AntiConformEnergySpectrumView\
|
||||||
|
$${PWD}/CoincidenceEventTimeView\
|
||||||
|
$${PWD}/NuclideAnalysisView
|
||||||
|
|
||||||
|
|
||||||
DEPENDPATH += \
|
DEPENDPATH += \
|
||||||
$${PWD}/BusyIndicator \
|
$${PWD}/BusyIndicator \
|
||||||
|
|
@ -57,12 +60,17 @@ DEPENDPATH += \
|
||||||
$${PWD}/2DSpectralCompliance \
|
$${PWD}/2DSpectralCompliance \
|
||||||
$${PWD}/ConformToTheEnergySpectrum \
|
$${PWD}/ConformToTheEnergySpectrum \
|
||||||
$${PWD}/NuclideLib \
|
$${PWD}/NuclideLib \
|
||||||
$${PWD}/AntiConformEnergySpectrumView
|
$${PWD}/AntiConformEnergySpectrumView\
|
||||||
|
$${PWD}/CoincidenceEventTimeView\
|
||||||
|
$${PWD}/NuclideAnalysisView
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
2DSpectralCompliance/TwoDSpectralCompliance.cpp \
|
2DSpectralCompliance/TwoDSpectralCompliance.cpp \
|
||||||
AboutDlg.cpp \
|
AboutDlg.cpp \
|
||||||
BusyIndicator/BusyIndicator.cpp \
|
BusyIndicator/BusyIndicator.cpp \
|
||||||
|
CoincidenceEventTimeView/CoincidenceEventTimeView.cpp \
|
||||||
CountRateAnalysisView/CountRateAnalysisView.cpp \
|
CountRateAnalysisView/CountRateAnalysisView.cpp \
|
||||||
CustomQwtPlot.cpp \
|
CustomQwtPlot.cpp \
|
||||||
DataProcessWorkPool.cpp \
|
DataProcessWorkPool.cpp \
|
||||||
|
|
@ -79,6 +87,7 @@ SOURCES += \
|
||||||
MeasureDeviceParamsConfigView/DeviceParamsSaveToSysDlg.cpp \
|
MeasureDeviceParamsConfigView/DeviceParamsSaveToSysDlg.cpp \
|
||||||
MeasureDeviceParamsConfigView/DeviceParamsTableForm.cpp \
|
MeasureDeviceParamsConfigView/DeviceParamsTableForm.cpp \
|
||||||
MeasureDeviceParamsConfigView/MeasureDeviceParamsConfigView.cpp \
|
MeasureDeviceParamsConfigView/MeasureDeviceParamsConfigView.cpp \
|
||||||
|
NuclideAnalysisView/NuclideAnalysisView.cpp \
|
||||||
NuclideLib/NuclideEditDialog.cpp \
|
NuclideLib/NuclideEditDialog.cpp \
|
||||||
NuclideLib/NuclideRayDialog.cpp \
|
NuclideLib/NuclideRayDialog.cpp \
|
||||||
NuclideLib/NuclideRayListDialog.cpp \
|
NuclideLib/NuclideRayListDialog.cpp \
|
||||||
|
|
@ -111,6 +120,7 @@ HEADERS += \
|
||||||
AboutDlg.h \
|
AboutDlg.h \
|
||||||
AnalysisTypeDefine.h \
|
AnalysisTypeDefine.h \
|
||||||
BusyIndicator/BusyIndicator.h \
|
BusyIndicator/BusyIndicator.h \
|
||||||
|
CoincidenceEventTimeView/CoincidenceEventTimeView.h \
|
||||||
CountRateAnalysisView/CountRateAnalysisView.h \
|
CountRateAnalysisView/CountRateAnalysisView.h \
|
||||||
CustomQwtPlot.h \
|
CustomQwtPlot.h \
|
||||||
DataProcessWorkPool.h \
|
DataProcessWorkPool.h \
|
||||||
|
|
@ -128,6 +138,7 @@ HEADERS += \
|
||||||
MeasureDeviceParamsConfigView/DeviceParamsSaveToSysDlg.h \
|
MeasureDeviceParamsConfigView/DeviceParamsSaveToSysDlg.h \
|
||||||
MeasureDeviceParamsConfigView/DeviceParamsTableForm.h \
|
MeasureDeviceParamsConfigView/DeviceParamsTableForm.h \
|
||||||
MeasureDeviceParamsConfigView/MeasureDeviceParamsConfigView.h \
|
MeasureDeviceParamsConfigView/MeasureDeviceParamsConfigView.h \
|
||||||
|
NuclideAnalysisView/NuclideAnalysisView.h \
|
||||||
NuclideLib/NuclideEditDialog.h \
|
NuclideLib/NuclideEditDialog.h \
|
||||||
NuclideLib/NuclideRayDialog.h \
|
NuclideLib/NuclideRayDialog.h \
|
||||||
NuclideLib/NuclideRayListDialog.h \
|
NuclideLib/NuclideRayListDialog.h \
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user