2026-03-19 18:43:03 +08:00
# include "EnergyScaleForm.h"
# include "ui_EnergyScaleForm.h"
2026-05-27 19:35:17 +08:00
# include <QDir>
# include <QJsonDocument>
# include <QJsonObject>
# include <QJsonArray>
# include <QJsonValue>
# include <QwtPlotCanvas>
# include <QwtText>
# include <QwtPlotCurve>
# include "CustomQwtPlot.h"
# include "DataCalcProcess/GaussPolyCoe.h"
# include "DataCalcProcess/MathModelDefine.h"
# include "DataCalcProcess/NolinearLeastSquaresCurveFit.h"
# include <QDebug>
# include <QDialog>
# include <QMessageBox>
# include <QInputDialog>
# include <QFileDialog>
2026-03-19 18:43:03 +08:00
EnergyScaleForm : : EnergyScaleForm ( QWidget * parent )
2026-05-27 19:35:17 +08:00
: MeasureAnalysisView ( parent )
2026-03-19 18:43:03 +08:00
, ui ( new Ui : : EnergyScaleForm )
2026-05-27 19:35:17 +08:00
, _plot ( nullptr )
, _rawDataCurve ( nullptr )
, _fitCurve ( nullptr )
, _rawDataSymbol ( nullptr )
, m_isLoadingTable ( false )
2026-03-19 18:43:03 +08:00
{
ui - > setupUi ( this ) ;
2026-05-27 19:35:17 +08:00
this - > _plot = new CustomQwtPlot ( this ) ;
ui - > layout_fittingCurve - > addWidget ( this - > _plot ) ;
_rawDataCurve = new QwtPlotCurve ( " 原始数据 " ) ;
_fitCurve = new QwtPlotCurve ( " 拟合曲线 " ) ;
_rawDataSymbol = new QwtSymbol ( QwtSymbol : : Ellipse ) ;
_rawDataSymbol - > setSize ( 8 ) ;
_rawDataSymbol - > setBrush ( Qt : : red ) ;
_rawDataSymbol - > setPen ( QPen ( Qt : : black , 1 ) ) ;
setupPlot ( ) ;
initComboBoxUi ( ) ;
initScaleDataTable ( ) ;
loadAllFilesInTheFolder ( ) ;
connect ( ui - > comboBox_channel , & QComboBox : : currentTextChanged , this , & EnergyScaleForm : : on_comboBox_channel_currentTextChanged ) ;
connect ( ui - > comboBox_fit_type , & QComboBox : : currentTextChanged , this , & EnergyScaleForm : : on_comboBox_fit_type_currentTextChanged ) ;
connect ( ui - > tablew_scale_data , & QTableWidget : : cellChanged , this , & EnergyScaleForm : : on_tablew_scale_data_cellChanged ) ;
2026-03-19 18:43:03 +08:00
}
EnergyScaleForm : : ~ EnergyScaleForm ( )
{
delete ui ;
}
2026-05-27 19:35:17 +08:00
void EnergyScaleForm : : InitViewWorkspace ( const QString & project_name )
{
}
void EnergyScaleForm : : 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 ( ) ;
2026-05-28 15:48:24 +08:00
QFileInfo info ( data_filename ) ;
QDir dir = info . dir ( ) ;
2026-05-27 19:35:17 +08:00
if ( QFileInfo ( data_filename ) . exists ( ) ) {
ui - > groupBox_3 - > hide ( ) ;
QFileInfo fileInfo ( data_filename ) ;
2026-05-28 15:48:24 +08:00
QString baseName = QString ( " [%1]%2 " ) . arg ( dir . dirName ( ) ) . arg ( fileInfo . baseName ( ) ) ;
2026-05-27 19:35:17 +08:00
ui - > lineEdit_name - > setText ( baseName ) ;
2026-05-28 15:48:24 +08:00
ui - > lineEdit_name - > setReadOnly ( true ) ;
2026-06-01 17:45:49 +08:00
ui - > groupBox_2 - > hide ( ) ;
2026-05-28 15:48:24 +08:00
ui - > pBtn_SaveAs - > setText ( QStringLiteral ( u " 保存到系统 " ) ) ;
2026-05-27 19:35:17 +08:00
m_currentFilePath = data_filename ;
QString errorMsg ;
m_channelList = parseJsonToChannels ( data_filename , errorMsg ) ;
on_comboBox_channel_currentTextChanged ( QStringLiteral ( u " 通道1 " ) ) ;
}
}
}
void EnergyScaleForm : : 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 " 道址 " ) ;
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 EnergyScaleForm : : loadAllFilesInTheFolder ( )
{
const QString & energy_scale_dir_path = QDir ( qApp - > applicationDirPath ( ) ) . filePath ( " configure/EnergyScale " ) ;
QDir dir ( energy_scale_dir_path ) ;
QFileInfoList infoList = dir . entryInfoList ( QDir : : Files | QDir : : Dirs | QDir : : NoDotAndDotDot ) ;
ui - > listWidget - > clear ( ) ;
for ( const QFileInfo & info : infoList ) {
QString displayName ;
if ( info . isFile ( ) ) {
displayName = info . baseName ( ) ;
} else {
displayName = info . fileName ( ) ;
}
QListWidgetItem * item = new QListWidgetItem ( displayName ) ;
item - > setData ( Qt : : UserRole , info . absoluteFilePath ( ) ) ;
ui - > listWidget - > addItem ( item ) ;
}
connect ( ui - > listWidget , & QListWidget : : itemDoubleClicked , this , & EnergyScaleForm : : onItemDoubleClicked ) ;
}
QMap < QString , ChannelData > EnergyScaleForm : : parseJsonToChannels ( const QString & filePath , QString & errorMsg )
{
QMap < QString , ChannelData > result ;
errorMsg . clear ( ) ;
QFile file ( filePath ) ;
if ( ! file . open ( QIODevice : : ReadOnly | QIODevice : : Text ) ) {
errorMsg = QString ( " 无法打开文件: %1 " ) . arg ( file . errorString ( ) ) ;
return result ;
}
QByteArray data = file . readAll ( ) ;
file . close ( ) ;
QJsonParseError parseError ;
QJsonDocument doc = QJsonDocument : : fromJson ( data , & parseError ) ;
if ( parseError . error ! = QJsonParseError : : NoError ) {
errorMsg = QString ( " JSON 解析错误: %1 " ) . arg ( parseError . errorString ( ) ) ;
return result ;
}
if ( ! doc . isObject ( ) ) {
errorMsg = " JSON 根节点不是对象 " ;
return result ;
}
QJsonObject rootObj = doc . object ( ) ;
if ( rootObj . contains ( " Remark " ) & & rootObj [ " Remark " ] . isString ( ) )
ui - > plainTextEdit_description - > setPlainText ( rootObj [ " Remark " ] . toString ( ) ) ;
for ( auto it = rootObj . begin ( ) ; it ! = rootObj . end ( ) ; + + it ) {
QString channelName = it . key ( ) ;
QJsonValue channelVal = it . value ( ) ;
if ( ! channelVal . isObject ( ) ) {
errorMsg + = QString ( " 通道 %1 的值不是对象,跳过 \n " ) . arg ( channelName ) ;
continue ;
}
QJsonObject channelObj = channelVal . toObject ( ) ;
ChannelData chData ;
if ( channelObj . contains ( " EnergyFitDegree " ) & & channelObj [ " EnergyFitDegree " ] . isDouble ( ) ) {
chData . energyFitDegree = channelObj [ " EnergyFitDegree " ] . toInt ( ) ;
} else {
errorMsg + = QString ( " 通道 %1 缺少 EnergyFitDegree 字段 \n " ) . arg ( channelName ) ;
continue ;
}
if ( channelObj . contains ( " EnergyFitResultCoeffs " ) & & channelObj [ " EnergyFitResultCoeffs " ] . isArray ( ) ) {
QJsonArray coeffsArr = channelObj [ " EnergyFitResultCoeffs " ] . toArray ( ) ;
for ( QJsonValue v : coeffsArr ) {
if ( v . isDouble ( ) )
chData . energyFitResultCoeffs . append ( v . toDouble ( ) ) ;
else
errorMsg + = QString ( " 通道 %1 的 EnergyFitResultCoeffs 包含非数字 \n " ) . arg ( channelName ) ;
}
} else {
errorMsg + = QString ( " 通道 %1 缺少 EnergyFitResultCoeffs 字段 \n " ) . arg ( channelName ) ;
}
if ( channelObj . contains ( " FitData " ) & & channelObj [ " FitData " ] . isArray ( ) ) {
QJsonArray fitDataArr = channelObj [ " FitData " ] . toArray ( ) ;
for ( QJsonValue rowVal : fitDataArr ) {
if ( ! rowVal . isArray ( ) ) {
errorMsg + = QString ( " 通道 %1 的 FitData 行不是数组 \n " ) . arg ( channelName ) ;
continue ;
}
QJsonArray rowArr = rowVal . toArray ( ) ;
if ( rowArr . size ( ) ! = 7 ) {
errorMsg + = QString ( " 通道 %1 的 FitData 行长度不为 7( 实际 %2) \n " )
. arg ( channelName ) . arg ( rowArr . size ( ) ) ;
continue ;
}
FitDataRow row ;
row . daoSite = rowArr [ 0 ] . toDouble ( ) ;
row . energy = rowArr [ 1 ] . toDouble ( ) ;
row . fittingEnergy = rowArr [ 2 ] . toDouble ( ) ;
row . energyFittingDeviation = rowArr [ 3 ] . toDouble ( ) ;
row . resolution = rowArr [ 4 ] . toDouble ( ) ;
row . fitResolution = rowArr [ 5 ] . toDouble ( ) ;
row . resolutionFittingDeviation = rowArr [ 6 ] . toDouble ( ) ;
chData . fitData . append ( row ) ;
}
} else {
errorMsg + = QString ( " 通道 %1 缺少 FitData 字段 \n " ) . arg ( channelName ) ;
}
if ( channelObj . contains ( " FwhmFitResultCoeffs " ) & & channelObj [ " FwhmFitResultCoeffs " ] . isArray ( ) ) {
QJsonArray fwhmArr = channelObj [ " FwhmFitResultCoeffs " ] . toArray ( ) ;
for ( QJsonValue v : fwhmArr ) {
if ( v . isDouble ( ) )
chData . fwhmFitResultCoeffs . append ( v . toDouble ( ) ) ;
else
errorMsg + = QString ( " 通道 %1 的 FwhmFitResultCoeffs 包含非数字 \n " ) . arg ( channelName ) ;
}
} else {
errorMsg + = QString ( " 通道 %1 缺少 FwhmFitResultCoeffs 字段 \n " ) . arg ( channelName ) ;
}
result . insert ( channelName , chData ) ;
}
if ( result . isEmpty ( ) & & errorMsg . isEmpty ( ) )
errorMsg = " 未找到任何通道数据。 " ;
return result ;
}
void EnergyScaleForm : : initComboBoxUi ( )
{
ui - > comboBox_fit_type - > addItem ( QStringLiteral ( u " 一次拟合 " ) ) ;
ui - > comboBox_fit_type - > addItem ( QStringLiteral ( u " 二次拟合 " ) ) ;
for ( int i = 1 ; i < = 32 ; + + i )
{
QString channelName = QStringLiteral ( u " 通道%1 " ) . arg ( i ) ;
ui - > comboBox_channel - > addItem ( channelName ) ;
if ( ! m_channelList . contains ( channelName ) ) {
ChannelData emptyData ;
emptyData . energyFitDegree = 1 ;
m_channelList . insert ( channelName , emptyData ) ;
}
}
}
void EnergyScaleForm : : initScaleDataTable ( )
{
QTableWidget * table = ui - > tablew_scale_data ;
table - > setColumnCount ( 7 ) ;
// 设置表格列名
QStringList headers = {
" 道址 " , " 能量 " , " 拟合能量 " , " 能量拟合偏差 " ,
" 分辨率 " , " 拟合分辨率 " , " 分辨率拟合偏差 "
} ;
table - > setHorizontalHeaderLabels ( headers ) ;
table - > setEditTriggers ( QTableWidget : : DoubleClicked | QTableWidget : : EditKeyPressed ) ;
table - > setSelectionBehavior ( QTableWidget : : SelectRows ) ; // 整行选中
table - > horizontalHeader ( ) - > setSectionResizeMode ( QHeaderView : : Stretch ) ;
}
void EnergyScaleForm : : showChannelData ( const QString channelName )
{
if ( ! m_channelList . contains ( channelName ) ) {
return ;
}
m_isLoadingTable = true ; // 防止触发cellChanged
ui - > tablew_scale_data - > setRowCount ( 0 ) ;
const ChannelData & chData = m_channelList [ channelName ] ;
switch ( chData . energyFitDegree ) {
case 1 :
{
ui - > comboBox_fit_type - > setCurrentIndex ( 0 ) ;
ui - > label_fit_type_text - > setText ( QStringLiteral ( u " y = a + bx " ) ) ;
QString coefficient = QStringLiteral ( u " a = %1 , b = %2 " ) . arg ( chData . energyFitResultCoeffs . at ( 0 ) ) . arg ( chData . energyFitResultCoeffs . at ( 1 ) ) ;
ui - > label_fit_result - > setText ( coefficient ) ;
} break ;
case 2 :
ui - > comboBox_fit_type - > setCurrentIndex ( 1 ) ;
ui - > label_fit_type_text - > setText ( QStringLiteral ( u " y = a + bx + c*x^2 " ) ) ;
QString coefficient = QStringLiteral ( u " a = %1 , b = %2, c = %3 " ) . arg ( chData . energyFitResultCoeffs . at ( 0 ) ) . arg ( chData . energyFitResultCoeffs . at ( 1 ) ) . arg ( chData . energyFitResultCoeffs . at ( 2 ) ) ;
ui - > label_fit_result - > setText ( coefficient ) ;
break ;
}
QString energyCoeffsStr ;
for ( int i = 0 ; i < chData . energyFitResultCoeffs . size ( ) ; + + i ) {
energyCoeffsStr + = QString ( " 系数%1: %2 " ) . arg ( i + 1 ) . arg ( chData . energyFitResultCoeffs [ i ] , 0 , ' f ' , 6 ) ;
}
QTableWidget * table = ui - > tablew_scale_data ;
table - > setRowCount ( chData . fitData . size ( ) ) ;
for ( int row = 0 ; row < chData . fitData . size ( ) ; + + row ) {
const FitDataRow & fitRow = chData . fitData [ row ] ;
table - > setItem ( row , 0 , new QTableWidgetItem ( QString : : number ( fitRow . daoSite , ' f ' , 3 ) ) ) ;
table - > setItem ( row , 1 , new QTableWidgetItem ( QString : : number ( fitRow . energy , ' f ' , 3 ) ) ) ;
table - > setItem ( row , 2 , new QTableWidgetItem ( QString : : number ( fitRow . fittingEnergy , ' f ' , 3 ) ) ) ;
table - > setItem ( row , 3 , new QTableWidgetItem ( QString : : number ( fitRow . energyFittingDeviation , ' f ' , 3 ) ) ) ;
table - > setItem ( row , 4 , new QTableWidgetItem ( QString : : number ( fitRow . resolution , ' f ' , 3 ) ) ) ;
table - > setItem ( row , 5 , new QTableWidgetItem ( QString : : number ( fitRow . fitResolution , ' f ' , 3 ) ) ) ;
table - > setItem ( row , 6 , new QTableWidgetItem ( QString : : number ( fitRow . resolutionFittingDeviation , ' f ' , 3 ) ) ) ;
for ( int col = 0 ; col < 7 ; + + col ) {
Qt : : ItemFlags flags = Qt : : ItemIsSelectable | Qt : : ItemIsEnabled ;
if ( col = = 0 | | col = = 1 | | col = = 4 ) {
flags | = Qt : : ItemIsEditable ;
}
table - > item ( row , col ) - > setFlags ( flags ) ;
}
}
m_isLoadingTable = false ;
}
void EnergyScaleForm : : showCurve ( )
{
clearPlot ( ) ;
QString channelName = ui - > comboBox_channel - > currentText ( ) ;
if ( ! m_channelList . contains ( channelName ) )
{
_plot - > replot ( ) ;
return ;
}
const ChannelData & chData = m_channelList [ channelName ] ;
if ( chData . fitData . isEmpty ( ) ) return ;
QVector < double > xRaw , yRaw ;
double xMin = 0 ;
double xMax = 4096 ;
for ( const FitDataRow & row : chData . fitData ) {
xRaw . append ( row . daoSite ) ;
yRaw . append ( row . energy ) ;
}
_rawDataCurve - > setSamples ( xRaw , yRaw ) ;
_rawDataCurve - > setSymbol ( _rawDataSymbol ) ;
_rawDataCurve - > setStyle ( QwtPlotCurve : : NoCurve ) ;
_rawDataCurve - > attach ( _plot ) ;
if ( ! chData . energyFitResultCoeffs . isEmpty ( ) ) {
QVector < QPointF > fitPoints = generateFitCurvePoints ( chData ) ;
_fitCurve - > setSamples ( fitPoints ) ;
_fitCurve - > setPen ( QPen ( Qt : : blue , 2 ) ) ; // 拟合曲线用蓝色粗线
_fitCurve - > setStyle ( QwtPlotCurve : : Lines ) ;
_fitCurve - > attach ( _plot ) ;
}
_plot - > replot ( ) ;
}
void EnergyScaleForm : : clearPlot ( )
{
_rawDataCurve - > detach ( ) ;
_fitCurve - > detach ( ) ;
_plot - > detachItems ( QwtPlotItem : : Rtti_PlotCurve , false ) ;
_plot - > replot ( ) ;
}
QVector < QPointF > EnergyScaleForm : : generateFitCurvePoints ( const ChannelData & chData )
{
int pointCount = 4096 ;
QVector < QPointF > points ;
if ( chData . energyFitResultCoeffs . isEmpty ( ) ) return points ;
for ( int i = 0 ; i < pointCount ; + + i ) {
double y = 0.0 ;
switch ( chData . energyFitDegree ) {
case 1 : // 一次拟合: y = a + b*x
y = LinearFunction ( i , chData . energyFitResultCoeffs [ 0 ] , chData . energyFitResultCoeffs [ 1 ] ) ;
break ;
case 2 : // 二次拟合: y = a + b*x + c*x²
if ( chData . energyFitResultCoeffs . size ( ) > = 3 ) {
y = QuadraticPolynomial ( i , chData . energyFitResultCoeffs [ 0 ] , chData . energyFitResultCoeffs [ 1 ] , chData . energyFitResultCoeffs [ 2 ] ) ;
}
break ;
default :
break ;
}
points . append ( QPointF ( i , y ) ) ;
}
return points ;
}
QVector < QPointF > EnergyScaleForm : : generateFitCurvePoints ( const double a , const double b , const double c )
{
int pointCount = 4096 ;
QVector < QPointF > points ;
// if (chData.energyFitResultCoeffs.isEmpty()) return points;
for ( int i = 0 ; i < pointCount ; + + i ) {
double y = 0.0 ;
switch ( ui - > comboBox_fit_type - > currentIndex ( ) + 1 ) {
case 1 : y = LinearFunction ( i , a , b ) ; ; break ;
case 2 : y = QuadraticPolynomial ( i , a , b , c ) ; break ;
}
points . append ( QPointF ( i , y ) ) ;
}
return points ;
}
void EnergyScaleForm : : calculateFitValues ( ChannelData & chData )
{
if ( chData . fitData . isEmpty ( ) )
return ;
if ( ! chData . energyFitResultCoeffs . isEmpty ( ) ) {
for ( auto & row : chData . fitData ) {
double x = row . daoSite ;
double fitE = 0.0 ;
if ( chData . energyFitDegree = = 1 & & chData . energyFitResultCoeffs . size ( ) > = 2 ) {
fitE = LinearFunction ( x , chData . energyFitResultCoeffs [ 0 ] , chData . energyFitResultCoeffs [ 1 ] ) ;
}
else if ( chData . energyFitDegree = = 2 & & chData . energyFitResultCoeffs . size ( ) > = 3 ) {
fitE = QuadraticPolynomial ( x , chData . energyFitResultCoeffs [ 0 ] , chData . energyFitResultCoeffs [ 1 ] , chData . energyFitResultCoeffs [ 2 ] ) ;
}
row . fittingEnergy = fitE ;
row . energyFittingDeviation = row . energy - fitE ;
}
}
if ( chData . fwhmFitResultCoeffs . size ( ) > = 2 )
{
arma : : vec p ( 2 ) ;
p ( 0 ) = chData . fwhmFitResultCoeffs [ 0 ] ; // k
p ( 1 ) = chData . fwhmFitResultCoeffs [ 1 ] ; // c
for ( auto & row : chData . fitData ) {
double E = row . fittingEnergy ;
if ( E < = 0 ) {
row . fitResolution = 0.0 ;
row . resolutionFittingDeviation = 0.0 ;
continue ;
}
double fitFwhm = FwhmModel ( E , p ) ;
row . fitResolution = fitFwhm ;
row . resolutionFittingDeviation = row . resolution - fitFwhm ;
}
}
else {
// 没有分辨率参数就清空
for ( auto & row : chData . fitData ) {
row . fitResolution = 0.0 ;
row . resolutionFittingDeviation = 0.0 ;
}
}
}
bool EnergyScaleForm : : fitFwhmModel ( ChannelData & chData )
{
std : : vector < double > E_list , fwhm_list ;
for ( const auto & row : chData . fitData ) {
if ( row . fittingEnergy > 0 & & row . resolution > 0 ) {
E_list . push_back ( row . fittingEnergy ) ;
fwhm_list . push_back ( row . resolution ) ;
}
}
if ( E_list . size ( ) < 2 ) {
return false ;
}
arma : : vec E ( E_list . data ( ) , E_list . size ( ) ) ;
arma : : vec FWHM ( fwhm_list . data ( ) , fwhm_list . size ( ) ) ;
2026-05-28 15:48:24 +08:00
2026-05-27 19:35:17 +08:00
arma : : vec params = NolinearLeastSquaresCurveFit : : Lsqcurvefit ( FwhmModel , E , FWHM , { 1.0 , 1.0 } ) ;
chData . fwhmFitResultCoeffs . clear ( ) ;
chData . fwhmFitResultCoeffs . append ( params ( 0 ) ) ; // k
chData . fwhmFitResultCoeffs . append ( params ( 1 ) ) ; // c
return true ;
}
bool EnergyScaleForm : : saveChannelDataToJson ( const QString & filePath )
{
if ( filePath . isEmpty ( ) ) return false ;
QJsonObject rootObj ;
2026-05-28 15:48:24 +08:00
QString remark ;
if ( systemEnble )
remark = ui - > plainTextEdit_description - > property ( " systemData " ) . toString ( ) ;
else
remark = ui - > plainTextEdit_description - > toPlainText ( ) . trimmed ( ) ;
2026-05-27 19:35:17 +08:00
rootObj [ " Remark " ] = remark ;
for ( auto it = m_channelList . begin ( ) ; it ! = m_channelList . end ( ) ; + + it ) {
QString channelName = it . key ( ) ;
const ChannelData & chData = it . value ( ) ;
QJsonObject channelObj ;
channelObj [ " EnergyFitDegree " ] = chData . energyFitDegree ;
// 能量拟合系数
QJsonArray energyCoeffsArr ;
for ( double coeff : chData . energyFitResultCoeffs ) {
energyCoeffsArr . append ( coeff ) ;
}
channelObj [ " EnergyFitResultCoeffs " ] = energyCoeffsArr ;
// 拟合数据
QJsonArray fitDataArr ;
for ( const FitDataRow & row : chData . fitData ) {
QJsonArray rowArr ;
rowArr . append ( row . daoSite ) ;
rowArr . append ( row . energy ) ;
rowArr . append ( row . fittingEnergy ) ;
rowArr . append ( row . energyFittingDeviation ) ;
rowArr . append ( row . resolution ) ;
rowArr . append ( row . fitResolution ) ;
rowArr . append ( row . resolutionFittingDeviation ) ;
fitDataArr . append ( rowArr ) ;
}
channelObj [ " FitData " ] = fitDataArr ;
QJsonArray fwhmCoeffsArr ;
for ( double coeff : chData . fwhmFitResultCoeffs ) {
fwhmCoeffsArr . append ( coeff ) ;
}
channelObj [ " FwhmFitResultCoeffs " ] = fwhmCoeffsArr ;
rootObj [ channelName ] = channelObj ;
}
QJsonDocument doc ( rootObj ) ;
QFile file ( filePath ) ;
if ( ! file . open ( QIODevice : : WriteOnly | QIODevice : : Text ) ) {
QMessageBox : : critical ( this , " 错误 " , QString ( " 保存文件失败:%1 " ) . arg ( file . errorString ( ) ) ) ;
return false ;
}
file . write ( doc . toJson ( QJsonDocument : : Indented ) ) ;
file . close ( ) ;
return true ;
}
bool EnergyScaleForm : : isDaoSiteDuplicated ( const QString & channelName , double daoSite )
{
if ( ! m_channelList . contains ( channelName ) ) return false ;
const auto & fitData = m_channelList [ channelName ] . fitData ;
for ( const auto & row : fitData ) {
if ( qAbs ( row . daoSite - daoSite ) < 1e-3 ) {
return true ;
}
}
return false ;
}
void EnergyScaleForm : : onItemDoubleClicked ( QListWidgetItem * item )
{
if ( ! item ) return ;
ui - > plainTextEdit_description - > clear ( ) ;
QString filePath = item - > data ( Qt : : UserRole ) . toString ( ) ;
if ( filePath . isEmpty ( ) ) return ;
ui - > lineEdit_name - > setText ( item - > text ( ) ) ;
m_currentFilePath = filePath ;
QString errorMsg ;
m_channelList = parseJsonToChannels ( filePath , errorMsg ) ;
on_comboBox_channel_currentTextChanged ( QStringLiteral ( u " 通道1 " ) ) ;
}
void EnergyScaleForm : : on_comboBox_channel_currentTextChanged ( const QString & text )
{
if ( text . isEmpty ( ) ) {
return ;
}
if ( ! m_channelList . contains ( text ) ) {
ChannelData emptyData ;
emptyData . energyFitDegree = 1 ;
m_channelList . insert ( text , emptyData ) ;
}
showChannelData ( text ) ;
showCurve ( ) ;
}
void EnergyScaleForm : : on_comboBox_fit_type_currentTextChanged ( const QString & text )
{
if ( text = = QStringLiteral ( u " 一次拟合 " ) ) {
ui - > label_fit_type_text - > setText ( QStringLiteral ( u " y = a + bx " ) ) ;
} else if ( text = = QStringLiteral ( u " 二次拟合 " ) ) {
ui - > label_fit_type_text - > setText ( QStringLiteral ( u " y = a + bx + c*x^2 " ) ) ;
}
showCurve ( ) ;
}
void EnergyScaleForm : : on_pBtn_Add_clicked ( )
{
QString channelName = ui - > comboBox_channel - > currentText ( ) ;
QDialog dialog ( this ) ;
dialog . setWindowTitle ( " 添加能量刻度点 " ) ;
dialog . setFixedSize ( 300 , 180 ) ; // 调整高度,预留分辨率输入
dialog . setModal ( true ) ;
QVBoxLayout * mainLayout = new QVBoxLayout ( & dialog ) ;
mainLayout - > setSpacing ( 15 ) ;
mainLayout - > setContentsMargins ( 20 , 20 , 20 , 20 ) ;
// 道址输入
QHBoxLayout * daoLayout = new QHBoxLayout ( ) ;
QLabel * daoLabel = new QLabel ( " 道址: " ) ;
QLineEdit * daoEdit = new QLineEdit ( ) ;
daoEdit - > setPlaceholderText ( " 请输入道址值(数字) " ) ;
QDoubleValidator * daoValidator = new QDoubleValidator ( 0 , 100000 , 3 , daoEdit ) ;
daoValidator - > setNotation ( QDoubleValidator : : StandardNotation ) ;
daoEdit - > setValidator ( daoValidator ) ;
daoLayout - > addWidget ( daoLabel ) ;
daoLayout - > addWidget ( daoEdit ) ;
// 能量输入
QHBoxLayout * energyLayout = new QHBoxLayout ( ) ;
QLabel * energyLabel = new QLabel ( " 能量: " ) ;
QLineEdit * energyEdit = new QLineEdit ( ) ;
energyEdit - > setPlaceholderText ( " 请输入能量值(数字) " ) ;
QDoubleValidator * energyValidator = new QDoubleValidator ( 0 , 10000 , 3 , energyEdit ) ;
energyValidator - > setNotation ( QDoubleValidator : : StandardNotation ) ;
energyEdit - > setValidator ( energyValidator ) ;
energyLayout - > addWidget ( energyLabel ) ;
energyLayout - > addWidget ( energyEdit ) ;
//分辨率输入
QHBoxLayout * resolutionLayout = new QHBoxLayout ( ) ;
QLabel * resolutionLabel = new QLabel ( " 分辨率: " ) ;
QLineEdit * resolutionEdit = new QLineEdit ( ) ;
resolutionEdit - > setPlaceholderText ( " 请输入分辨率(数字) " ) ;
QDoubleValidator * resolutionValidator = new QDoubleValidator ( 0 , 1000 , 3 , resolutionEdit ) ;
resolutionValidator - > setNotation ( QDoubleValidator : : StandardNotation ) ;
resolutionEdit - > setValidator ( resolutionValidator ) ;
resolutionLayout - > addWidget ( resolutionLabel ) ;
resolutionLayout - > addWidget ( resolutionEdit ) ;
// 按钮行
QHBoxLayout * btnLayout = new QHBoxLayout ( ) ;
QPushButton * okBtn = new QPushButton ( " 确定 " ) ;
QPushButton * cancelBtn = new QPushButton ( " 取消 " ) ;
okBtn - > setDefault ( true ) ;
btnLayout - > addStretch ( ) ;
btnLayout - > addWidget ( okBtn ) ;
btnLayout - > addWidget ( cancelBtn ) ;
mainLayout - > addLayout ( daoLayout ) ;
mainLayout - > addLayout ( energyLayout ) ;
mainLayout - > addLayout ( resolutionLayout ) ;
mainLayout - > addLayout ( btnLayout ) ;
connect ( okBtn , & QPushButton : : clicked , & dialog , & QDialog : : accept ) ;
connect ( cancelBtn , & QPushButton : : clicked , & dialog , & QDialog : : reject ) ;
daoEdit - > setFocus ( ) ;
if ( dialog . exec ( ) ! = QDialog : : Accepted ) {
return ;
}
QString daoStr = daoEdit - > text ( ) . trimmed ( ) ;
QString energyStr = energyEdit - > text ( ) . trimmed ( ) ;
QString resolutionStr = resolutionEdit - > text ( ) . trimmed ( ) ;
if ( daoStr . isEmpty ( ) | | energyStr . isEmpty ( ) ) {
QMessageBox : : warning ( this , " 输入错误 " , " 道址和能量不能为空 " ) ;
return ;
}
bool daoOk = false , energyOk = false , resolutionOk = false ;
double daoSite = daoStr . toDouble ( & daoOk ) ;
double energy = energyStr . toDouble ( & energyOk ) ;
double resolution = resolutionStr . isEmpty ( ) ? 0.0 : resolutionStr . toDouble ( & resolutionOk ) ;
if ( ! daoOk | | ! energyOk | | ( ! resolutionStr . isEmpty ( ) & & ! resolutionOk ) ) {
QMessageBox : : warning ( this , " 输入错误 " , " 请输入有效的数字 " ) ;
return ;
}
if ( isDaoSiteDuplicated ( channelName , daoSite ) ) {
QMessageBox : : warning ( this , " 输入错误 " , " 该道址已存在,无法重复添加 " ) ;
return ;
}
ChannelData & chData = m_channelList [ channelName ] ;
QTableWidget * table = ui - > tablew_scale_data ;
FitDataRow newRow ;
newRow . daoSite = daoSite ;
newRow . energy = energy ;
newRow . resolution = resolution ;
newRow . fittingEnergy = 0.0 ;
newRow . energyFittingDeviation = 0.0 ;
newRow . fitResolution = 0.0 ;
newRow . resolutionFittingDeviation = 0.0 ;
chData . fitData . append ( newRow ) ;
m_isLoadingTable = true ;
int newRowIndex = table - > rowCount ( ) ;
table - > insertRow ( newRowIndex ) ;
table - > setItem ( newRowIndex , 0 , new QTableWidgetItem ( QString : : number ( daoSite , ' f ' , 3 ) ) ) ;
table - > setItem ( newRowIndex , 1 , new QTableWidgetItem ( QString : : number ( energy , ' f ' , 3 ) ) ) ;
table - > setItem ( newRowIndex , 4 , new QTableWidgetItem ( QString : : number ( resolution , ' f ' , 3 ) ) ) ;
for ( int col = 2 ; col < 7 ; + + col ) {
if ( col ! = 4 ) {
table - > setItem ( newRowIndex , col , new QTableWidgetItem ( " 0.000 " ) ) ;
}
}
for ( int col = 0 ; col < 7 ; + + col ) {
Qt : : ItemFlags flags = Qt : : ItemIsSelectable | Qt : : ItemIsEnabled ;
if ( col = = 0 | | col = = 1 | | col = = 4 ) {
flags | = Qt : : ItemIsEditable ;
}
table - > item ( newRowIndex , col ) - > setFlags ( flags ) ;
}
m_isLoadingTable = false ;
table - > scrollToBottom ( ) ;
table - > selectRow ( newRowIndex ) ;
showCurve ( ) ;
QMessageBox : : information ( this , " 成功 " , " 数据点添加成功 " ) ;
}
void EnergyScaleForm : : on_pBtn_Delete_clicked ( )
{
QTableWidget * table = ui - > tablew_scale_data ;
int currentRow = table - > currentRow ( ) ;
if ( currentRow < 0 | | currentRow > = table - > rowCount ( ) ) {
QMessageBox : : warning ( this , " 提示 " , " 请选中要删除的行 " ) ;
return ;
}
if ( QMessageBox : : question ( this , " 确认 " , " 是否删除选中的行? " , QMessageBox : : Yes | QMessageBox : : No ) ! = QMessageBox : : Yes ) {
return ;
}
table - > removeRow ( currentRow ) ;
QString channelName = ui - > comboBox_channel - > currentText ( ) ;
if ( m_channelList . contains ( channelName ) ) {
ChannelData & chData = m_channelList [ channelName ] ;
if ( currentRow < chData . fitData . size ( ) ) {
chData . fitData . remove ( currentRow ) ;
}
// 删除后重新计算拟合值(如果有拟合系数)
calculateFitValues ( chData ) ;
// 刷新表格显示
showChannelData ( channelName ) ;
}
showCurve ( ) ;
}
void EnergyScaleForm : : on_pBtn_fitting_clicked ( )
{
QString channelName = ui - > comboBox_channel - > currentText ( ) ;
if ( ! m_channelList . contains ( channelName ) ) {
QMessageBox : : warning ( this , " 拟合失败 " , " 当前通道无数据 " ) ;
return ;
}
ChannelData & chData = m_channelList [ channelName ] ;
int rowCount = ui - > tablew_scale_data - > rowCount ( ) ;
int fitDegree = ui - > comboBox_fit_type - > currentIndex ( ) + 1 ;
int minEnergyPoints = ( fitDegree = = 1 ) ? 2 : 3 ;
if ( rowCount < minEnergyPoints ) {
QMessageBox : : warning ( this , " 拟合失败 " ,
QString ( " 至少需要%1个数据点才能进行%2 " ) . arg ( minEnergyPoints ) . arg ( fitDegree = = 1 ? " 一次拟合 " : " 二次拟合 " ) ) ;
return ;
}
std : : vector < double > xRow , yRow ;
for ( int i = 0 ; i < rowCount ; + + i ) {
QTableWidgetItem * daoItem = ui - > tablew_scale_data - > item ( i , 0 ) ;
QTableWidgetItem * energyItem = ui - > tablew_scale_data - > item ( i , 1 ) ;
if ( ! daoItem | | ! energyItem ) continue ;
bool daoOk = false , energyOk = false ;
double dao = daoItem - > text ( ) . toDouble ( & daoOk ) ;
double energy = energyItem - > text ( ) . toDouble ( & energyOk ) ;
if ( daoOk & & energyOk ) {
xRow . push_back ( dao ) ;
yRow . push_back ( energy ) ;
}
}
if ( xRow . size ( ) < minEnergyPoints | | yRow . size ( ) < minEnergyPoints ) {
QMessageBox : : warning ( this , " 拟合失败 " , " 有效能量数据点不足 " ) ;
return ;
}
std : : vector < double > energyCoeff = GaussPolyCoe : : PolynomialFit ( xRow , yRow , fitDegree ) ;
if ( energyCoeff . size ( ) < fitDegree + 1 ) {
QMessageBox : : warning ( this , " 拟合失败 " , " 能量拟合计算出错 " ) ;
return ;
}
chData . energyFitDegree = fitDegree ;
chData . energyFitResultCoeffs . clear ( ) ;
for ( double coeff : energyCoeff ) {
chData . energyFitResultCoeffs . append ( coeff ) ;
}
fitFwhmModel ( chData ) ;
calculateFitValues ( chData ) ;
m_isLoadingTable = true ;
showChannelData ( channelName ) ;
m_isLoadingTable = false ;
showCurve ( ) ;
QString energyMsg ;
if ( fitDegree = = 1 ) {
energyMsg = QString ( " 能量拟合成功: a = %1 , b = %2 " )
. arg ( energyCoeff [ 0 ] , 0 , ' f ' , 6 )
. arg ( energyCoeff [ 1 ] , 0 , ' f ' , 6 ) ;
} else {
energyMsg = QString ( " 能量拟合成功: a = %1 , b = %2 , c = %3 " )
. arg ( energyCoeff [ 0 ] , 0 , ' f ' , 6 )
. arg ( energyCoeff [ 1 ] , 0 , ' f ' , 6 )
. arg ( energyCoeff [ 2 ] , 0 , ' f ' , 6 ) ;
}
}
void EnergyScaleForm : : on_tablew_scale_data_cellChanged ( int row , int column )
{
if ( m_isLoadingTable ) return ;
QString channelName = ui - > comboBox_channel - > currentText ( ) ;
if ( ! m_channelList . contains ( channelName ) ) return ;
if ( row < 0 | | row > = m_channelList [ channelName ] . fitData . size ( ) ) return ;
ChannelData & chData = m_channelList [ channelName ] ;
FitDataRow & currentRow = chData . fitData [ row ] ;
QTableWidgetItem * item = ui - > tablew_scale_data - > item ( row , column ) ;
if ( ! item ) return ;
bool ok = false ;
double value = item - > text ( ) . toDouble ( & ok ) ;
if ( ! ok ) {
// 输入非数字时恢复原值
m_isLoadingTable = true ;
if ( column = = 0 ) {
item - > setText ( QString : : number ( currentRow . daoSite , ' f ' , 3 ) ) ;
} else if ( column = = 1 ) {
item - > setText ( QString : : number ( currentRow . energy , ' f ' , 3 ) ) ;
} else if ( column = = 4 ) {
item - > setText ( QString : : number ( currentRow . resolution , ' f ' , 3 ) ) ;
}
m_isLoadingTable = false ;
QMessageBox : : warning ( this , " 输入错误 " , " 请输入有效的数字 " ) ;
return ;
}
bool needRecalc = false ;
if ( column = = 0 ) {
// 检查道址重复
if ( isDaoSiteDuplicated ( channelName , value ) & & qAbs ( currentRow . daoSite - value ) > 1e-3 ) {
m_isLoadingTable = true ;
item - > setText ( QString : : number ( currentRow . daoSite , ' f ' , 3 ) ) ;
m_isLoadingTable = false ;
QMessageBox : : warning ( this , " 提示 " , " 道址重复,修改失败 " ) ;
return ;
}
currentRow . daoSite = value ;
needRecalc = true ;
} else if ( column = = 1 ) {
currentRow . energy = value ;
needRecalc = true ;
} else if ( column = = 4 ) {
currentRow . resolution = value ;
needRecalc = true ;
}
if ( needRecalc ) {
2026-05-28 15:48:24 +08:00
// calculateFitValues(chData);
// m_isLoadingTable = true;
// showChannelData(channelName);
// m_isLoadingTable = false;
// showCurve();
on_pBtn_fitting_clicked ( ) ;
2026-05-27 19:35:17 +08:00
}
2026-05-28 15:48:24 +08:00
2026-05-27 19:35:17 +08:00
}
void EnergyScaleForm : : on_pBtn_SaveAs_clicked ( )
{
2026-05-28 15:48:24 +08:00
QString SaveAsName = ui - > pBtn_SaveAs - > text ( ) ;
QString targetFilePath ;
QString fileName ;
QString remark ;
if ( SaveAsName . contains ( " 保存到系统 " ) )
{
systemEnble = true ;
QDialog dialog ( this ) ;
dialog . setWindowTitle ( QStringLiteral ( u " 保存到系统 - 能量刻度配置 " ) ) ;
dialog . setFixedSize ( 400 , 250 ) ;
dialog . setModal ( true ) ;
QVBoxLayout * mainLayout = new QVBoxLayout ( & dialog ) ;
mainLayout - > setSpacing ( 15 ) ;
mainLayout - > setContentsMargins ( 20 , 20 , 20 , 20 ) ;
QHBoxLayout * nameLayout = new QHBoxLayout ( ) ;
QLabel * nameLabel = new QLabel ( QStringLiteral ( u " 能量刻度名称: " ) ) ;
QLineEdit * nameEdit = new QLineEdit ( ) ;
nameEdit - > setPlaceholderText ( QStringLiteral ( u " 请输入刻度名称: " ) ) ;
if ( ! ui - > lineEdit_name - > text ( ) . isEmpty ( ) ) {
QString baseName = ui - > lineEdit_name - > text ( ) ;
baseName = baseName . contains ( " [ " ) ? baseName . split ( " ] " ) . last ( ) . trimmed ( ) : baseName ;
nameEdit - > setText ( baseName ) ;
}
nameLayout - > addWidget ( nameLabel ) ;
nameLayout - > addWidget ( nameEdit ) ;
// 备注输入框
QVBoxLayout * remarkLayout = new QVBoxLayout ( ) ;
QLabel * remarkLabel = new QLabel ( QStringLiteral ( u " 备注: " ) ) ;
QTextEdit * remarkEdit = new QTextEdit ( ) ;
remarkEdit - > setPlaceholderText ( QStringLiteral ( u " 请输入备注信息(可选) " ) ) ;
remarkEdit - > setPlainText ( ui - > plainTextEdit_description - > toPlainText ( ) ) ; // 填充现有备注
remarkLayout - > addWidget ( remarkLabel ) ;
remarkLayout - > addWidget ( remarkEdit ) ;
// 按钮组
QHBoxLayout * btnLayout = new QHBoxLayout ( ) ;
QPushButton * okBtn = new QPushButton ( QStringLiteral ( u " 保存 " ) ) ;
QPushButton * cancelBtn = new QPushButton ( QStringLiteral ( u " 取消 " ) ) ;
okBtn - > setDefault ( true ) ;
btnLayout - > addStretch ( ) ;
btnLayout - > addWidget ( okBtn ) ;
btnLayout - > addWidget ( cancelBtn ) ;
// 组装布局
mainLayout - > addLayout ( nameLayout ) ;
mainLayout - > addLayout ( remarkLayout ) ;
mainLayout - > addLayout ( btnLayout ) ;
connect ( okBtn , & QPushButton : : clicked , & dialog , & QDialog : : accept ) ;
connect ( cancelBtn , & QPushButton : : clicked , & dialog , & QDialog : : reject ) ;
if ( dialog . exec ( ) ! = QDialog : : Accepted ) {
return ;
}
2026-05-27 19:35:17 +08:00
2026-05-28 15:48:24 +08:00
fileName = nameEdit - > text ( ) . trimmed ( ) ;
remark = remarkEdit - > toPlainText ( ) . trimmed ( ) ;
if ( fileName . isEmpty ( ) ) {
QMessageBox : : warning ( this , QStringLiteral ( u " 输入错误 " ) , QStringLiteral ( u " 能量刻度名称不能为空! " ) ) ;
return ;
}
QString defaultDir = QDir ( qApp - > applicationDirPath ( ) ) . filePath ( " configure/EnergyScale " ) ;
2026-05-27 19:35:17 +08:00
2026-05-28 15:48:24 +08:00
QDir dir ( defaultDir ) ;
if ( ! dir . exists ( ) & & ! dir . mkpath ( " . " ) ) {
QMessageBox : : critical ( this , QStringLiteral ( u " 错误 " ) , QStringLiteral ( u " 无法创建目录:%1 " ) . arg ( defaultDir ) ) ;
return ;
}
targetFilePath = dir . filePath ( fileName + " .json " ) ; // 强制.json后缀
if ( QFile : : exists ( targetFilePath ) ) {
QMessageBox : : StandardButton ret = QMessageBox : : question (
this ,
QStringLiteral ( u " 文件已存在 " ) ,
QStringLiteral ( u " 名称为“%1”的能量刻度文件已存在, 是否覆盖? " ) . arg ( fileName ) ,
QMessageBox : : Yes | QMessageBox : : No ,
QMessageBox : : No
) ;
if ( ret ! = QMessageBox : : Yes ) {
return ;
}
}
ui - > plainTextEdit_description - > setProperty ( " systemData " , remark ) ;
} else {
systemEnble = false ;
// 选择保存路径
QString defaultDir = QDir ( qApp - > applicationDirPath ( ) ) . filePath ( " configure/EnergyScale " ) ;
2026-06-01 17:45:49 +08:00
targetFilePath = QFileDialog : : getSaveFileName ( this ,
2026-05-28 15:48:24 +08:00
" 另存为能量刻度文件 " ,
defaultDir ,
" JSON文件 (*.json);;所有文件 (*.*) " ) ;
if ( targetFilePath . isEmpty ( ) ) {
return ;
}
// 确保后缀是.json
if ( ! targetFilePath . endsWith ( " .json " , Qt : : CaseInsensitive ) ) {
targetFilePath + = " .json " ;
}
}
2026-05-27 19:35:17 +08:00
// 保存文件
2026-05-28 15:48:24 +08:00
if ( saveChannelDataToJson ( targetFilePath ) ) {
// m_currentFilePath = targetFilePath; // 更新当前文件路径
// ui->lineEdit_name->setText(QFileInfo(targetFilePath).baseName());
2026-05-27 19:35:17 +08:00
loadAllFilesInTheFolder ( ) ;
}
}
void EnergyScaleForm : : on_pBtn_Save_clicked ( )
{
2026-05-28 15:48:24 +08:00
systemEnble = false ;
2026-05-27 19:35:17 +08:00
if ( saveChannelDataToJson ( m_currentFilePath ) ) {
QMessageBox : : information ( this , " 成功 " , " 数据保存成功 " ) ;
} else {
QMessageBox : : critical ( this , " 失败 " , " 数据保存失败 " ) ;
}
}
void EnergyScaleForm : : on_pBtn_Add_File_clicked ( )
{
bool isOk = false ;
QString fileName = QInputDialog : : getText ( this ,
QStringLiteral ( u " 新建能量刻度文件 " ) ,
QStringLiteral ( u " 请输入文件名(无需后缀): " ) ,
QLineEdit : : Normal ,
QStringLiteral ( u " 新刻度文件 " ) ,
& isOk ) ;
if ( ! isOk | | fileName . trimmed ( ) . isEmpty ( ) ) {
return ; // 用户取消或输入为空
}
fileName = fileName . trimmed ( ) ;
const QString energyScaleDir = QDir ( qApp - > applicationDirPath ( ) ) . filePath ( " configure/EnergyScale " ) ;
QDir dir ( energyScaleDir ) ;
if ( ! dir . exists ( ) & & ! dir . mkpath ( " . " ) ) {
QMessageBox : : critical ( this , QStringLiteral ( u " 错误 " ) ,
QStringLiteral ( u " 无法创建目录:%1 " ) . arg ( energyScaleDir ) ) ;
return ;
}
QString filePath = dir . filePath ( fileName + " .json " ) ;
if ( QFile : : exists ( filePath ) ) {
QMessageBox : : warning ( this , QStringLiteral ( u " 提示 " ) ,
QStringLiteral ( u " 文件%1已存在, 请更换文件名 " ) . arg ( fileName ) ) ;
return ;
}
QJsonObject rootObj ;
for ( int i = 1 ; i < = 32 ; + + i ) {
QString channelName = QStringLiteral ( u " 通道%1 " ) . arg ( i ) ;
QJsonObject channelObj ;
channelObj [ " EnergyFitDegree " ] = 1 ; // 默认一次拟合
channelObj [ " EnergyFitResultCoeffs " ] = QJsonArray ( ) ; // 空系数
channelObj [ " FitData " ] = QJsonArray ( ) ; // 空拟合数据
channelObj [ " FwhmFitResultCoeffs " ] = QJsonArray ( ) ; // 空分辨率系数
rootObj [ channelName ] = channelObj ;
}
QJsonDocument doc ( rootObj ) ;
QFile file ( filePath ) ;
if ( ! file . open ( QIODevice : : WriteOnly | QIODevice : : Text ) ) {
QMessageBox : : critical ( this , QStringLiteral ( u " 错误 " ) ,
QStringLiteral ( u " 无法创建文件:%1 \n %2 " ) . arg ( filePath ) . arg ( file . errorString ( ) ) ) ;
return ;
}
file . write ( doc . toJson ( QJsonDocument : : Indented ) ) ;
file . close ( ) ;
loadAllFilesInTheFolder ( ) ;
for ( int i = 0 ; i < ui - > listWidget - > count ( ) ; + + i ) {
QListWidgetItem * item = ui - > listWidget - > item ( i ) ;
if ( item - > text ( ) = = fileName ) {
ui - > listWidget - > setCurrentItem ( item ) ;
break ;
}
}
QMessageBox : : information ( this , QStringLiteral ( u " 成功 " ) ,
QStringLiteral ( u " 文件%1创建成功 " ) . arg ( fileName + " .json " ) ) ;
}
void EnergyScaleForm : : on_pBtn_Delete_File_clicked ( )
{
QListWidgetItem * selectedItem = ui - > listWidget - > currentItem ( ) ;
if ( ! selectedItem ) {
QMessageBox : : warning ( this , QStringLiteral ( u " 提示 " ) ,
QStringLiteral ( u " 请先选中要删除的文件/文件夹 " ) ) ;
return ;
}
QString filePath = selectedItem - > data ( Qt : : UserRole ) . toString ( ) ;
if ( filePath . isEmpty ( ) ) {
QMessageBox : : warning ( this , QStringLiteral ( u " 错误 " ) ,
QStringLiteral ( u " 无法获取文件路径 " ) ) ;
return ;
}
QMessageBox : : StandardButton ret = QMessageBox : : question ( this ,
QStringLiteral ( u " 确认删除 " ) ,
QStringLiteral ( u " 是否确定删除%1? \n 删除后无法恢复! " ) . arg ( selectedItem - > text ( ) ) ,
QMessageBox : : Yes | QMessageBox : : No ,
QMessageBox : : No ) ;
if ( ret ! = QMessageBox : : Yes ) {
return ;
}
bool isDeleted = false ;
QFileInfo fileInfo ( filePath ) ;
if ( fileInfo . isFile ( ) ) {
QFile file ( filePath ) ;
isDeleted = file . remove ( ) ;
}
if ( isDeleted ) {
loadAllFilesInTheFolder ( ) ;
if ( m_currentFilePath = = filePath ) {
m_currentFilePath . clear ( ) ;
ui - > lineEdit_name - > clear ( ) ;
ui - > tablew_scale_data - > setRowCount ( 0 ) ;
clearPlot ( ) ;
_plot - > replot ( ) ;
ui - > label_fit_result - > clear ( ) ;
ui - > label_fit_type_text - > clear ( ) ;
}
QMessageBox : : information ( this , QStringLiteral ( u " 成功 " ) ,
QStringLiteral ( u " 删除成功 " ) ) ;
} else {
QMessageBox : : critical ( this , QStringLiteral ( u " 错误 " ) ,
QStringLiteral ( u " 删除失败:%1 " ) . arg ( filePath ) ) ;
}
}