@ -1,9 +1,11 @@
# include "nmWxAutomaticfittingStart.h"
# include "nmWxAutomaticfittingStart.h"
# include <QtGui/QApplication>
# include <QtGui/QApplication>
# include <QDesktopWidget>
# include <QtCore/QEvent>
# include <QtCore/QEvent>
# include <QtGui/QMouseEvent>
# include <QtGui/QMouseEvent>
# include <QtGui/QFont>
# include <QtGui/QFont>
# include <QScrollBar>
# include <QScrollBar>
# include <QTextDocument>
# include <QList>
# include <QList>
# include <QPainter>
# include <QPainter>
# include <QPaintEvent>
# include <QPaintEvent>
@ -33,7 +35,8 @@ nmAutomaticFittingCurveChart::nmAutomaticFittingCurveChart(QWidget* parent)
, m_bestFitness ( 0.0 )
, m_bestFitness ( 0.0 )
, m_pseudoPressureMode ( false )
, m_pseudoPressureMode ( false )
{
{
setMinimumHeight ( 220 ) ;
// 保留绘图空间,同时允许小屏幕压缩曲线区域的高度。
setMinimumHeight ( 160 ) ;
setMinimumWidth ( 420 ) ;
setMinimumWidth ( 420 ) ;
}
}
@ -181,7 +184,8 @@ void nmAutomaticFittingCurveChart::paintEvent(QPaintEvent* event)
QPainter painter ( this ) ;
QPainter painter ( this ) ;
painter . setRenderHint ( QPainter : : Antialiasing ) ;
painter . setRenderHint ( QPainter : : Antialiasing ) ;
painter . fillRect ( rect ( ) , QColor ( 240 , 240 , 240 ) ) ;
// 保持全宽白色绘图区,曲线和实测标记沿用原有红绿配色。
painter . fillRect ( rect ( ) , Qt : : white ) ;
const int marginLeft = 62 ;
const int marginLeft = 62 ;
const int marginTop = 18 ;
const int marginTop = 18 ;
@ -191,7 +195,7 @@ void nmAutomaticFittingCurveChart::paintEvent(QPaintEvent* event)
qMax ( 10 , width ( ) - marginLeft - marginRight ) ,
qMax ( 10 , width ( ) - marginLeft - marginRight ) ,
qMax ( 10 , height ( ) - marginTop - marginBottom ) ) ;
qMax ( 10 , height ( ) - marginTop - marginBottom ) ) ;
painter . fillRect ( m_chartRect , Q Color( 252 , 252 , 252 ) ) ;
painter . fillRect ( m_chartRect , Q t: : white ) ;
drawGrid ( painter ) ;
drawGrid ( painter ) ;
drawAxes ( painter ) ;
drawAxes ( painter ) ;
drawCurveLine ( painter , m_bestPressure , QColor ( 250 , 74 , 74 ) ) ;
drawCurveLine ( painter , m_bestPressure , QColor ( 250 , 74 , 74 ) ) ;
@ -210,7 +214,7 @@ void nmAutomaticFittingCurveChart::drawGrid(QPainter& painter)
int yStart = static_cast < int > ( qFloor ( m_logRange . top ( ) ) ) ;
int yStart = static_cast < int > ( qFloor ( m_logRange . top ( ) ) ) ;
int yEnd = static_cast < int > ( qCeil ( m_logRange . bottom ( ) ) ) ;
int yEnd = static_cast < int > ( qCeil ( m_logRange . bottom ( ) ) ) ;
painter . setPen ( QPen ( QColor ( 2 36, 236 , 236 ) , 1 , Qt : : SolidLine ) ) ;
painter . setPen ( QPen ( QColor ( 2 47, 248 , 250 ) , 1 , Qt : : SolidLine ) ) ;
for ( int decade = xStart ; decade < = xEnd ; + + decade ) {
for ( int decade = xStart ; decade < = xEnd ; + + decade ) {
for ( int multiplier = 2 ; multiplier < = 9 ; + + multiplier ) {
for ( int multiplier = 2 ; multiplier < = 9 ; + + multiplier ) {
double value = decade + qLn ( static_cast < double > ( multiplier ) ) / qLn ( 10.0 ) ;
double value = decade + qLn ( static_cast < double > ( multiplier ) ) / qLn ( 10.0 ) ;
@ -237,7 +241,7 @@ void nmAutomaticFittingCurveChart::drawGrid(QPainter& painter)
}
}
}
}
painter . setPen ( QPen ( QColor ( 2 14, 214 , 214 ) , 1 , Qt : : SolidLine ) ) ;
painter . setPen ( QPen ( QColor ( 2 28, 232 , 238 ) , 1 , Qt : : SolidLine ) ) ;
for ( int x = xStart ; x < = xEnd ; + + x ) {
for ( int x = xStart ; x < = xEnd ; + + x ) {
if ( x < m_logRange . left ( ) | | x > m_logRange . right ( ) ) {
if ( x < m_logRange . left ( ) | | x > m_logRange . right ( ) ) {
continue ;
continue ;
@ -397,167 +401,237 @@ nmWxAutomaticfittingStart::nmWxAutomaticfittingStart(QWidget *parent)
// 设置窗口属性
// 设置窗口属性
setWindowTitle ( tr ( " Auto Fitting Progress " ) ) ;
setWindowTitle ( tr ( " Auto Fitting Progress " ) ) ;
setMinimumSize ( 1000 , 650 ) ;
// 初始尺寸随所在屏幕变化,最小尺寸交给实际控件布局决定。
resize ( sizeHint ( ) ) ;
setModal ( false ) ;
setModal ( false ) ;
}
}
QSize nmWxAutomaticfittingStart : : sizeHint ( ) const
{
// 加宽进程窗口,为曲线和完整日志行留出空间,同时保留屏幕边缘。
QDesktopWidget * desktop = QApplication : : desktop ( ) ;
if ( desktop = = nullptr ) return iDlgBase : : sizeHint ( ) ;
const QRect available = desktop - > availableGeometry ( parentWidget ( ) ? parentWidget ( ) - > window ( ) : this ) ;
return QSize ( available . width ( ) * 75 / 100 , available . height ( ) * 65 / 100 ) ;
}
nmWxAutomaticfittingStart : : ~ nmWxAutomaticfittingStart ( )
nmWxAutomaticfittingStart : : ~ nmWxAutomaticfittingStart ( )
{
{
}
}
void nmWxAutomaticfittingStart : : setupUI ( )
void nmWxAutomaticfittingStart : : setupUI ( )
{
{
// 创建主要布局
// 曲线和日志左右并排,参数横排占满下方整行,底部使用一行汇总。
mainLayout = new QHBoxLayout ( ) ;
setObjectName ( " autoFittingProgress " ) ;
leftLayout = new QVBoxLayout ( ) ;
setFont ( QFont ( " Microsoft YaHei " , 9 ) ) ;
rightLayout = new QVBoxLayout ( ) ;
setStyleSheet (
" #autoFittingProgress { background: #ffffff; color: #233247; } "
// 设置左右布局
" #autoFittingProgress QGroupBox { background: #ffffff; color: #233247; border: none; margin-top: 0; padding-top: 0; font-weight: bold; } "
" #autoFittingProgress QLabel { color: #66768a; background: transparent; font-weight: normal; } "
" #autoFittingProgress QGroupBox#fittingSummary { padding-top: 0; } "
" #autoFittingProgress QGroupBox#fittingSummary QLabel { font-size: 14px; color: #46556b; } "
" #autoFittingProgress QWidget#parameterStrip { background: #ffffff; border-top: 1px solid #e3e8ef; } "
" #autoFittingProgress QWidget#parameterSeparator { background: #e3e8ef; } "
" #autoFittingProgress QLabel#parameterName { font-size: 12px; } "
" #autoFittingProgress QLabel#parameterValue { color: #233247; font-size: 18px; font-weight: 500; } "
" #autoFittingProgress QGroupBox#fittingSummary QLabel#summaryValue { color: #233247; } "
" #autoFittingProgress QGroupBox#fittingSummary QLabel#stateBadge { background: #edf3fc; color: #366baf; border-radius: 5px; padding: 4px 10px; font-size: 12px; } "
" #autoFittingProgress QGroupBox#fittingLog { padding-top: 0; } "
" #autoFittingProgress QLabel#sectionHeading { color: #233247; font-size: 13px; font-weight: bold; } "
" #autoFittingProgress QWidget#fittingFooter { background: #ffffff; border-top: 1px solid #e3e8ef; } "
" #autoFittingProgress QLabel#resultSummary { color: #66768a; font-size: 14px; } "
" #autoFittingProgress QLabel#stageStatus { color: #66768a; font-size: 12px; } "
" #autoFittingProgress QLabel#runSummary { color: #46556b; font-size: 14px; } "
" #autoFittingProgress QTextEdit { border: none; background: #ffffff; color: #233247; font-size: 13px; font-weight: normal; selection-background-color: #eaf1fb; selection-color: #233247; } "
" #autoFittingProgress QPushButton { background: #ffffff; color: #46556b; border: 1px solid #cfd7e2; border-radius: 5px; padding: 8px 22px; min-width: 64px; min-height: 20px; } "
" #autoFittingProgress QPushButton:hover { background: #edf3fc; border-color: #9bb7db; } "
" #autoFittingProgress QPushButton:pressed { background: #dce8f8; } "
" #autoFittingProgress QPushButton:disabled { background: #f0f2f5; color: #98a2b1; border-color: #e0e5ec; } "
" #autoFittingProgress QPushButton#logToggle { border: none; background: transparent; color: #738091; min-width: 0; padding: 3px 8px; } "
" #autoFittingProgress QPushButton#logToggle:hover { color: #396fc0; } "
" #autoFittingProgress QSplitter::handle { background: #ffffff; } " ) ;
// 控件复用原有数据更新逻辑,仅重新组织所属区域。
setupParameterArea ( ) ;
setupParameterArea ( ) ;
setupTableArea ( ) ;
setup ParameterStrip ( ) ;
setupChartArea ( ) ;
setupChartArea ( ) ;
setupLogArea ( ) ;
setupControlArea ( ) ;
setupControlArea ( ) ;
setupLogArea ( ) ;
// 左侧布局
// 日志只占右侧较窄区域,两侧底边对齐,分隔条允许调整宽度。
leftLayout - > addWidget ( parameterGroup ) ;
rightSplitter = new QSplitter ( Qt : : Horizontal , this ) ;
leftLayout - > addStretch ( ) ;
rightSplitter - > setHandleWidth ( 4 ) ;
leftLayout - > addWidget ( tableGroup ) ;
// 右侧布局
rightSplitter = new QSplitter ( Qt : : Vertical , this ) ;
rightSplitter - > addWidget ( chartGroup ) ;
rightSplitter - > addWidget ( chartGroup ) ;
rightSplitter - > addWidget ( logGroup ) ;
rightSplitter - > addWidget ( logGroup ) ;
rightSplitter - > setStretchFactor ( 0 , 3 ) ;
rightSplitter - > setStretchFactor ( 0 , 1 ) ;
rightSplitter - > setStretchFactor ( 1 , 2 ) ;
rightSplitter - > setStretchFactor ( 1 , 1 ) ;
rightSplitter - > setSizes ( QList < int > ( ) < < 320 < < 260 ) ;
rightSplitter - > setChildrenCollapsible ( false ) ;
rightLayout - > addWidget ( rightSplitter ) ;
rightSplitter - > setSizes ( QList < int > ( ) < < 650 < < 350 ) ;
// 主布局
mainLayout - > addLayout ( leftLayout , 1 ) ;
mainLayout - > addLayout ( rightLayout , 2 ) ;
// 控制区域布局
// 控制区域布局
QHBoxLayout * controlLayout = new QHBoxLayout ( ) ;
QWidget * footer = new QWidget ( this ) ;
controlLayout - > addWidget ( progressBar ) ;
footer - > setObjectName ( " fittingFooter " ) ;
footer - > setAttribute ( Qt : : WA_StyledBackground , true ) ;
QHBoxLayout * controlLayout = new QHBoxLayout ( footer ) ;
controlLayout - > setContentsMargins ( 22 , 14 , 22 , 14 ) ;
controlLayout - > setSpacing ( 24 ) ;
controlLayout - > addWidget ( resultSummary ) ;
controlLayout - > addWidget ( runSummary ) ;
controlLayout - > addStretch ( ) ;
controlLayout - > addWidget ( progressBar , 1 ) ;
controlLayout - > addWidget ( stopButton ) ;
controlLayout - > addWidget ( stopButton ) ;
QVBoxLayout * overallLayout = new QVBoxLayout ( ) ;
QVBoxLayout * overallLayout = new QVBoxLayout ( ) ;
overallLayout - > addLayout ( mainLayout ) ;
overallLayout - > setContentsMargins ( 0 , 0 , 0 , 0 ) ;
overallLayout - > addLayout ( controlLayout ) ;
overallLayout - > setSpacing ( 0 ) ;
overallLayout - > addWidget ( parameterGroup ) ;
overallLayout - > addWidget ( rightSplitter , 1 ) ;
overallLayout - > addWidget ( parameterStrip ) ;
overallLayout - > addWidget ( footer ) ;
setLayout ( overallLayout ) ;
setLayout ( overallLayout ) ;
}
}
void nmWxAutomaticfittingStart : : setupParameterArea ( )
void nmWxAutomaticfittingStart : : setupParameterArea ( )
{
{
parameterGroup = new QGroupBox ( tr ( " Parameter Display " ) , this ) ;
parameterGroup = new QGroupBox ( this ) ;
parameterGroup - > set FixedWidth( 280 ) ;
parameterGroup - > set ObjectName( " fittingSummary " ) ;
QGridLayout * paramLayout = new QGridLayout ( parameterGroup ) ;
QGridLayout * paramLayout = new QGridLayout ( parameterGroup ) ;
paramLayout - > setContentsMargins ( 22 , 19 , 22 , 17 ) ;
paramLayout - > setHorizontalSpacing ( 12 ) ;
paramLayout - > setVerticalSpacing ( 8 ) ;
// 创建标签
// 创建标签
algorithmTypeLabel = new QLabel ( tr ( " Algorithm: " ) ) ;
algorithmTypeLabel = new QLabel ( tr ( " Algorithm: " ) ) ;
currentIterationLabel = new QLabel ( tr ( " Current Iteration: " ) ) ;
currentIterationLabel = new QLabel ( tr ( " Iterations: " ) ) ;
maxIterationLabel = new QLabel ( tr ( " Max Iteration: " ) ) ;
currentComfortLabel = new QLabel ( tr ( " Current Error: " ) ) ;
currentComfortLabel = new QLabel ( tr ( " Current Error: " ) ) ;
bestComfortLabel = new QLabel ( tr ( " Best Error: " ) ) ;
bestComfortLabel = new QLabel ( tr ( " Best Error: " ) ) ;
targetPrecisionLabel = new QLabel ( tr ( " Target Precision :" ) ) ;
targetPrecisionLabel = new QLabel ( tr ( " Target error :" ) ) ;
targetWellLabel = new QLabel ( tr ( " Target Well: " ) ) ;
targetWellLabel = new QLabel ( tr ( " Target Well: " ) ) ;
// 创建数值显示标签
// 创建数值显示标签
algorithmTypeValue = new QLabel ( " PSO " ) ;
algorithmTypeValue = new QLabel ( " PSO " ) ;
currentIterationValue = new QLabel ( " 0 " ) ;
stateBadge = new QLabel ( tr ( " Waiting for fitting to start " ) ) ;
maxIterationValue = new QLabel ( " 100 " ) ;
stateBadge - > setObjectName ( " stateBadge " ) ;
currentIterationValue = new QLabel ( " 0 / 100 " ) ;
currentIterationValue - > setObjectName ( " summaryValue " ) ;
currentComfortValue = new QLabel ( " N/A " ) ;
currentComfortValue = new QLabel ( " N/A " ) ;
bestComfortValue = new QLabel ( " N/A " ) ;
bestComfortValue = new QLabel ( " N/A " ) ;
targetPrecisionValue = new QLabel ( " 0.001 " ) ;
targetPrecisionValue = new QLabel ( " 0.001 " ) ;
targetWellValue = new QLabel ( " N/A " ) ;
targetWellValue = new QLabel ( " N/A " ) ;
algorithmTypeValue - > setObjectName ( " summaryValue " ) ;
// 添加到布局
targetWellValue - > setObjectName ( " summaryValue " ) ;
paramLayout - > addWidget ( algorithmTypeLabel , 0 , 0 ) ;
targetPrecisionValue - > setObjectName ( " summaryValue " ) ;
paramLayout - > addWidget ( algorithmTypeValue , 0 , 1 ) ;
paramLayout - > addWidget ( currentIterationLabel , 1 , 0 ) ;
// 顶部统一显示累计迭代数和上限; PSO 的额外误差信息放在第二行。
paramLayout - > addWidget ( currentIterationValue , 1 , 1 ) ;
paramLayout - > addWidget ( targetWellLabel , 0 , 0 ) ;
paramLayout - > addWidget ( maxIterationLabel , 2 , 0 ) ;
paramLayout - > addWidget ( targetWellValue , 0 , 1 ) ;
paramLayout - > addWidget ( maxIterationValue , 2 , 1 ) ;
paramLayout - > addWidget ( algorithmTypeLabel , 0 , 2 ) ;
paramLayout - > addWidget ( currentComfortLabel , 3 , 0 ) ;
paramLayout - > addWidget ( algorithmTypeValue , 0 , 3 ) ;
paramLayout - > addWidget ( currentComfortValue , 3 , 1 ) ;
paramLayout - > addWidget ( targetPrecisionLabel , 0 , 4 ) ;
paramLayout - > addWidget ( bestComfortLabel , 4 , 0 ) ;
paramLayout - > addWidget ( targetPrecisionValue , 0 , 5 ) ;
paramLayout - > addWidget ( bestComfortValue , 4 , 1 ) ;
paramLayout - > addWidget ( currentIterationLabel , 0 , 6 ) ;
paramLayout - > addWidget ( targetPrecisionLabel , 5 , 0 ) ;
paramLayout - > addWidget ( currentIterationValue , 0 , 7 ) ;
paramLayout - > addWidget ( targetPrecisionValue , 5 , 1 ) ;
paramLayout - > addWidget ( stateBadge , 0 , 9 , Qt : : AlignRight | Qt : : AlignVCenter ) ;
paramLayout - > addWidget ( targetWellLabel , 6 , 0 ) ;
paramLayout - > addWidget ( currentComfortLabel , 1 , 0 ) ;
paramLayout - > addWidget ( targetWellValue , 6 , 1 ) ;
paramLayout - > addWidget ( currentComfortValue , 1 , 1 ) ;
paramLayout - > addWidget ( bestComfortLabel , 1 , 2 ) ;
paramLayout - > addWidget ( bestComfortValue , 1 , 3 ) ;
paramLayout - > setColumnStretch ( 8 , 1 ) ;
targetWellValue - > setWordWrap ( true ) ;
parameterGroup - > setLayout ( paramLayout ) ;
parameterGroup - > setLayout ( paramLayout ) ;
}
}
void nmWxAutomaticfittingStart : : setup TableArea ( )
void nmWxAutomaticfittingStart : : setup ParameterStrip ( )
{
{
tableGroup = new QGroupBox ( tr ( " Parameter Table " ) , this ) ;
// 参数独占曲线和日志下方的整行,横向均分空间,不保留尾部空白。
tableGroup - > setFixedWidth ( 300 ) ;
parameterStrip = new QWidget ( this ) ;
parameterStrip - > setObjectName ( " parameterStrip " ) ;
QVBoxLayout * tableLayout = new QVBoxLayout ( tableGroup ) ;
parameterStrip - > setAttribute ( Qt : : WA_StyledBackground , true ) ;
parameterStrip - > setSizePolicy ( QSizePolicy : : Expanding , QSizePolicy : : Preferred ) ;
tableWidget = new QTableWidget ( 0 , 2 , this ) ;
// 标题与参数共用网格,竖线跨越两行,上下留白均为 4 像素。
tableWidget - > setHorizontalHeaderLabels ( QStringList ( ) < < tr ( " Parameter Name " ) < < tr ( " Optimal Value " ) ) ;
parameterLayout = new QGridLayout ( parameterStrip ) ;
parameterLayout - > setContentsMargins ( 22 , 4 , 22 , 4 ) ;
// 设置表格属性
parameterLayout - > setHorizontalSpacing ( 0 ) ;
tableWidget - > setAlternatingRowColors ( true ) ;
parameterLayout - > setVerticalSpacing ( 2 ) ;
tableWidget - > setSelectionBehavior ( QAbstractItemView : : SelectRows ) ;
tableWidget - > setEditTriggers ( QAbstractItemView : : NoEditTriggers ) ;
tableWidget - > verticalHeader ( ) - > setVisible ( false ) ;
tableWidget - > setMinimumHeight ( 310 ) ;
// 设置列宽
QHeaderView * header = tableWidget - > horizontalHeader ( ) ;
header - > setResizeMode ( 0 , QHeaderView : : ResizeToContents ) ;
header - > setResizeMode ( 1 , QHeaderView : : Stretch ) ;
// 设置表格填充整个区域
tableWidget - > setSizePolicy ( QSizePolicy : : Expanding , QSizePolicy : : Expanding ) ;
// 隐藏滚动条
tableWidget - > setHorizontalScrollBarPolicy ( Qt : : ScrollBarAlwaysOff ) ;
tableLayout - > addWidget ( tableWidget ) ;
tableGroup - > setLayout ( tableLayout ) ;
}
}
void nmWxAutomaticfittingStart : : setupChartArea ( )
void nmWxAutomaticfittingStart : : setupChartArea ( )
{
{
chartGroup = new QGroupBox ( tr ( " Fitting Curve " ) , this ) ;
// 曲线上方仅保留标题。
chartGroup = new QGroupBox ( this ) ;
QVBoxLayout * chartLayout = new QVBoxLayout ( chartGroup ) ;
QVBoxLayout * chartLayout = new QVBoxLayout ( chartGroup ) ;
QLabel * heading = new QLabel ( tr ( " Fitting Curve " ) , chartGroup ) ;
heading - > setObjectName ( " sectionHeading " ) ;
chartLayout - > addWidget ( heading ) ;
curveChart = new nmAutomaticFittingCurveChart ( chartGroup ) ;
curveChart = new nmAutomaticFittingCurveChart ( chartGroup ) ;
curveChart - > setSizePolicy ( QSizePolicy : : Expanding , QSizePolicy : : Expanding ) ;
curveChart - > setSizePolicy ( QSizePolicy : : Expanding , QSizePolicy : : Expanding ) ;
chartLayout - > set Margin( 6 ) ;
chartLayout - > setContentsMargins ( 22 , 17 , 22 , 12 ) ;
chartLayout - > addWidget ( curveChart ) ;
chartLayout - > addWidget ( curveChart ) ;
chartGroup - > setLayout ( chartLayout ) ;
chartGroup - > setLayout ( chartLayout ) ;
chartGroup - > setMinimumHeight ( 2 4 0) ;
chartGroup - > setMinimumHeight ( 2 0 0) ;
}
}
void nmWxAutomaticfittingStart : : setupLogArea ( )
void nmWxAutomaticfittingStart : : setupLogArea ( )
{
{
logGroup = new QGroupBox ( tr ( " Log Window " ) , this ) ;
// 日志标题始终可见,正文收起时仍继续接收日志。
logGroup = new QGroupBox ( this ) ;
logGroup - > setObjectName ( " fittingLog " ) ;
QVBoxLayout * logLayout = new QVBoxLayout ( logGroup ) ;
QVBoxLayout * logLayout = new QVBoxLayout ( logGroup ) ;
logLayout - > setContentsMargins ( 18 , 13 , 22 , 16 ) ;
logLayout - > setSpacing ( 8 ) ;
logLayout - > setAlignment ( Qt : : AlignTop ) ;
QHBoxLayout * logHeader = new QHBoxLayout ( ) ;
QLabel * heading = new QLabel ( tr ( " Fitting process " ) , logGroup ) ;
heading - > setObjectName ( " sectionHeading " ) ;
logToggle = new QPushButton ( tr ( " Collapse " ) , logGroup ) ;
logToggle - > setObjectName ( " logToggle " ) ;
logToggle - > setAutoDefault ( false ) ;
logHeader - > addWidget ( heading ) ;
logHeader - > addStretch ( ) ;
logHeader - > addWidget ( logToggle ) ;
logLayout - > addLayout ( logHeader ) ;
// 阶段状态放到标题下方,避免挤占窄日志区的标题和按钮。
logLayout - > addWidget ( stageStatus ) ;
connect ( logToggle , SIGNAL ( clicked ( ) ) , this , SLOT ( onToggleLog ( ) ) ) ;
logTextEdit = new QTextEdit ( this ) ;
logTextEdit = new QTextEdit ( this ) ;
logTextEdit - > setReadOnly ( true ) ;
logTextEdit - > setReadOnly ( true ) ;
logTextEdit - > setFont ( QFont ( " Consolas " , 9 ) ) ;
// 小屏幕允许缩短可见日志区域,完整内容仍可通过滚动查看。
logTextEdit - > setMinimumHeight ( 48 ) ;
logTextEdit - > setMinimumWidth ( 180 ) ;
logTextEdit - > setFont ( font ( ) ) ;
// 正文与标题左对齐,沿用窗口白底,不额外绘制日志底色。
logTextEdit - > document ( ) - > setDocumentMargin ( 0 ) ;
// 添加初始日志
// 添加初始日志
addLogMessage ( tr ( " System initialization completed " ) ) ;
addLogMessage ( tr ( " System initialization completed " ) ) ;
addLogMessage ( tr ( " Waiting for fitting to start " ) ) ;
addLogMessage ( tr ( " Waiting for fitting to start " ) ) ;
logLayout - > addWidget ( logTextEdit ) ;
logLayout - > addWidget ( logTextEdit , 1 );
logGroup - > setLayout ( logLayout ) ;
logGroup - > setLayout ( logLayout ) ;
}
}
void nmWxAutomaticfittingStart : : setupControlArea ( )
void nmWxAutomaticfittingStart : : setupControlArea ( )
{
{
// 运行状态放在拟合过程标题下方;底部汇总保持单行。
stageStatus = new QLabel ( tr ( " Waiting for fitting to start " ) , this ) ;
stageStatus - > setObjectName ( " stageStatus " ) ;
stageStatus - > setWordWrap ( true ) ;
stageStatus - > hide ( ) ;
resultSummary = new QLabel ( this ) ;
resultSummary - > setObjectName ( " resultSummary " ) ;
resultSummary - > setTextFormat ( Qt : : RichText ) ;
resultSummary - > setWordWrap ( false ) ;
resultSummary - > hide ( ) ;
runSummary = new QLabel ( this ) ;
runSummary - > setObjectName ( " runSummary " ) ;
runSummary - > setWordWrap ( false ) ;
runSummary - > hide ( ) ;
// 进度条
// 进度条
progressBar = new QProgressBar ( this ) ;
progressBar = new QProgressBar ( this ) ;
progressBar - > setRange ( 0 , 100 ) ;
progressBar - > setRange ( 0 , 100 ) ;
@ -571,7 +645,6 @@ void nmWxAutomaticfittingStart::setupControlArea()
// 停止按钮
// 停止按钮
stopButton = new QPushButton ( tr ( " Stop " ) , this ) ;
stopButton = new QPushButton ( tr ( " Stop " ) , this ) ;
stopButton - > setFixedSize ( 80 , 30 ) ;
stopButton - > setEnabled ( false ) ;
stopButton - > setEnabled ( false ) ;
// 连接信号槽
// 连接信号槽
@ -583,10 +656,10 @@ void nmWxAutomaticfittingStart::setAutoFitter(nmCalculationAutoFitPSO* autoFitte
m_autoFitterPSO = autoFitter ;
m_autoFitterPSO = autoFitter ;
m_autoFitterLM = nullptr ;
m_autoFitterLM = nullptr ;
m_algorithmName = " PSO " ;
m_algorithmName = " PSO " ;
updateAlgorithmDisplay ( ) ;
// 更新算法类型显示
// 更新算法类型显示
algorithmTypeValue - > setText ( " PSO " ) ;
algorithmTypeValue - > setText ( " PSO " ) ;
algorithmTypeValue - > setStyleSheet ( " QLabel { color: blue; font-weight: bold; } " ) ;
if ( m_autoFitterPSO ) {
if ( m_autoFitterPSO ) {
connect ( m_autoFitterPSO , SIGNAL ( progressUpdated ( int , double ) ) ,
connect ( m_autoFitterPSO , SIGNAL ( progressUpdated ( int , double ) ) ,
@ -612,13 +685,15 @@ void nmWxAutomaticfittingStart::setAutoFitter(nmCalculationAutoFitLM* autoFitter
m_autoFitterPSO = nullptr ;
m_autoFitterPSO = nullptr ;
m_autoFitterLM = autoFitter ;
m_autoFitterLM = autoFitter ;
m_algorithmName = " LM " ;
m_algorithmName = " LM " ;
updateAlgorithmDisplay ( ) ;
// LM 日志由优化器统一组织,清除通用初始化提示。
// LM 日志由优化器统一组织,清除通用初始化提示。
logTextEdit - > clear ( ) ;
logTextEdit - > clear ( ) ;
algorithmTypeValue - > setText ( m_algorithmName ) ;
algorithmTypeValue - > setText ( m_algorithmName ) ;
algorithmTypeValue - > setStyleSheet ( " QLabel { color: blue; font-weight: bold; } " ) ;
if ( m_autoFitterLM ) {
if ( m_autoFitterLM ) {
connect ( m_autoFitterLM , SIGNAL ( fittingStageChanged ( int ) ) ,
this , SLOT ( onLMStageChanged ( int ) ) ) ;
connect ( m_autoFitterLM , SIGNAL ( progressUpdated ( int , double ) ) ,
connect ( m_autoFitterLM , SIGNAL ( progressUpdated ( int , double ) ) ,
this , SLOT ( onFittingProgress ( int , double ) ) ) ;
this , SLOT ( onFittingProgress ( int , double ) ) ) ;
connect ( m_autoFitterLM , SIGNAL ( fittingFinished ( bool , QString ) ) ,
connect ( m_autoFitterLM , SIGNAL ( fittingFinished ( bool , QString ) ) ,
@ -634,14 +709,48 @@ void nmWxAutomaticfittingStart::setAutoFitter(nmCalculationAutoFitLM* autoFitter
}
}
}
}
void nmWxAutomaticfittingStart : : updateAlgorithmDisplay ( )
{
// 迭代数始终在顶部显示, PSO 保留原有额外误差和进度条。
const bool lm = m_autoFitterLM ! = nullptr ;
QLabel * psoLabels [ ] = { currentComfortLabel , currentComfortValue ,
bestComfortLabel , bestComfortValue } ;
for ( int i = 0 ; i < 4 ; + + i ) psoLabels [ i ] - > setVisible ( ! lm ) ;
progressBar - > setVisible ( ! lm ) ;
stageStatus - > setVisible ( lm ) ;
resultSummary - > setVisible ( lm ) ;
if ( lm ) updateCurrentError ( m_autoFitterLM - > getBestFitness ( ) ) ;
if ( lm ) onLMStageChanged ( 0 ) ;
}
void nmWxAutomaticfittingStart : : onLMStageChanged ( int stage )
{
// 仅更新拟合过程区域的运行状态,不在曲线上方增加阶段栏。
const QString stages [ ] = { tr ( " Calculating initial error... " ) , tr ( " Height alignment " ) ,
tr ( " Shape adjustment " ) , tr ( " Total-error adjustment " ) } ;
stageStatus - > setText ( stages [ stage ] ) ;
}
void nmWxAutomaticfittingStart : : onToggleLog ( )
{
// 收起正文时把横向空间让给曲线,保留标题和按钮以便重新展开。
const bool collapse = ! logTextEdit - > isHidden ( ) ;
if ( collapse ) expandedLogSizes = rightSplitter - > sizes ( ) ;
logTextEdit - > setVisible ( ! collapse ) ;
logToggle - > setText ( collapse ? tr ( " Expand " ) : tr ( " Collapse " ) ) ;
logGroup - > layout ( ) - > activate ( ) ;
logGroup - > setMaximumWidth ( collapse ? logGroup - > minimumSizeHint ( ) . width ( ) : QWIDGETSIZE_MAX ) ;
if ( ! collapse & & ! expandedLogSizes . isEmpty ( ) ) rightSplitter - > setSizes ( expandedLogSizes ) ;
}
void nmWxAutomaticfittingStart : : setFittingParameters ( int maxIterations , double targetError , const QString & wellName )
void nmWxAutomaticfittingStart : : setFittingParameters ( int maxIterations , double targetError , const QString & wellName )
{
{
m_maxIterations = maxIterations ;
m_maxIterations = maxIterations ;
m_targetError = targetError ;
m_targetError = targetError ;
m_wellName = wellName ;
m_wellName = wellName ;
maxIterationValue - > setText ( QString : : number ( maxIterations ) ) ;
currentIterationValue- > setText ( QString ( " 0 / %1 " ) . arg ( maxIterations ) ) ;
targetPrecisionValue - > setText ( formatScientific ( targetError ) ) ;
targetPrecisionValue - > setText ( QString: : number ( targetError , ' g ' , 6 ) ) ;
targetWellValue - > setText ( wellName ) ;
targetWellValue - > setText ( wellName ) ;
progressBar - > setRange ( 0 , maxIterations ) ;
progressBar - > setRange ( 0 , maxIterations ) ;
@ -654,6 +763,7 @@ void nmWxAutomaticfittingStart::setFittingParameters(int maxIterations, double t
void nmWxAutomaticfittingStart : : markFittingStarted ( )
void nmWxAutomaticfittingStart : : markFittingStarted ( )
{
{
m_startTime = QDateTime : : currentDateTime ( ) ;
m_startTime = QDateTime : : currentDateTime ( ) ;
stateBadge - > setText ( tr ( " Fitting in progress " ) ) ;
const QString algorithmName = m_algorithmName ;
const QString algorithmName = m_algorithmName ;
QString timestamp = m_startTime . toString ( " yyyy-MM-dd hh:mm:ss " ) ;
QString timestamp = m_startTime . toString ( " yyyy-MM-dd hh:mm:ss " ) ;
@ -663,12 +773,56 @@ void nmWxAutomaticfittingStart::markFittingStarted()
. arg ( timestamp ) ) ;
. arg ( timestamp ) ) ;
}
}
void nmWxAutomaticfittingStart : : setSelectedParameters ( const QStringList & parameterNames )
void nmWxAutomaticfittingStart : : setSelectedParameters ( const QStringList & parameterNames ,
const QStringList & parameterUnits )
{
{
m_selectedParameters = parameterNames ;
// 仅在选择变化时重建标签,拟合期间只更新数值,避免布局反复抖动。
QLayoutItem * item = nullptr ;
while ( ( item = parameterLayout - > takeAt ( 0 ) ) ! = nullptr ) {
delete item - > widget ( ) ;
delete item ;
}
parameterValues . clear ( ) ;
for ( int column = 0 ; column < parameterLayout - > columnCount ( ) ; + + column ) {
parameterLayout - > setColumnStretch ( column , 0 ) ;
}
QLabel * heading = new QLabel ( tr ( " Current parameters " ) , parameterStrip ) ;
heading - > setObjectName ( " sectionHeading " ) ;
parameterLayout - > addWidget ( heading , 0 , 0 ) ;
for ( int i = 0 ; i < parameterNames . size ( ) ; + + i ) {
// 名称和单位在上、数值在下,相邻参数用细竖线分隔。
QWidget * cell = new QWidget ( parameterStrip ) ;
cell - > setAttribute ( Qt : : WA_StyledBackground , true ) ;
QVBoxLayout * cellLayout = new QVBoxLayout ( cell ) ;
cellLayout - > setContentsMargins ( 12 , 0 , 12 , 0 ) ;
cellLayout - > setSpacing ( 2 ) ;
const QString unit = parameterUnits . value ( i ) ;
QLabel * name = new QLabel ( parameterNames [ i ] + ( unit . isEmpty ( ) ? QString ( ) : " / " + unit ) , cell ) ;
name - > setObjectName ( " parameterName " ) ;
name - > setWordWrap ( true ) ;
name - > setAlignment ( Qt : : AlignCenter ) ;
QLabel * value = new QLabel ( " -- " , cell ) ;
value - > setObjectName ( " parameterValue " ) ;
value - > setAlignment ( Qt : : AlignCenter ) ;
value - > setTextInteractionFlags ( Qt : : TextSelectableByMouse ) ;
cellLayout - > addWidget ( name , 1 ) ;
cellLayout - > addWidget ( value ) ;
parameterLayout - > addWidget ( cell , 1 , i * 2 ) ;
parameterLayout - > setColumnStretch ( i * 2 , 1 ) ;
if ( i > 0 ) {
// 分隔线独立于参数单元格,避免标题导致上下间距不一致。
QWidget * separator = new QWidget ( parameterStrip ) ;
separator - > setObjectName ( " parameterSeparator " ) ;
separator - > setAttribute ( Qt : : WA_StyledBackground , true ) ;
separator - > setFixedWidth ( 1 ) ;
parameterLayout - > addWidget ( separator , 0 , i * 2 - 1 , 2 , 1 ) ;
}
parameterValues . append ( value ) ;
}
parameterStrip - > setVisible ( ! parameterNames . isEmpty ( ) ) ;
// 立即更新参数表格
// 立即 显示当前已接受的参数值。
updateParameterTable ( ) ;
updateParameter Values ( ) ;
const QString algorithmName = m_algorithmName ;
const QString algorithmName = m_algorithmName ;
if ( ! m_autoFitterLM ) addLogMessage ( tr ( " %1 selected parameters: %2 " ) . arg ( algorithmName ) . arg ( parameterNames . join ( " , " ) ) ) ;
if ( ! m_autoFitterLM ) addLogMessage ( tr ( " %1 selected parameters: %2 " ) . arg ( algorithmName ) . arg ( parameterNames . join ( " , " ) ) ) ;
@ -690,17 +844,17 @@ void nmWxAutomaticfittingStart::setPseudoPressureMode(bool enabled)
void nmWxAutomaticfittingStart : : onFittingProgress ( int iteration , double fitness )
void nmWxAutomaticfittingStart : : onFittingProgress ( int iteration , double fitness )
{
{
// LM 预调整没有固定总步数,单独显示阶段;整体阶段从局部迭代 0 开始计进度 。
// LM 各阶段显示累计迭代次数;达到上限之前仍可能提前收敛,不显示完成百分比 。
if ( m_autoFitterLM & & iteration < 0 ) {
currentIterationValue - > setText ( QString ( " %1 / %2 " ) . arg ( qMax ( 0 , iteration ) ) . arg ( m_maxIterations ) ) ;
progressBar - > setValue ( 0 ) ;
if ( m_autoFitterLM ) {
progressBar- > setFormat ( tr ( " Pre-adjustment " ) ) ;
updateCurrentError( fitness ) ;
currentIterationValue - > setText ( tr ( " Pre-adjustment " ) ) ;
return ;
} else {
} else {
int displayIteration = qMax ( m_autoFitterLM ? 0 : 1 , qMin ( iteration , m_maxIterations ) ) ;
int displayIteration = qMax ( 1 , qMin ( iteration , m_maxIterations ) ) ;
progressBar - > setValue ( displayIteration ) ;
progressBar - > setValue ( displayIteration ) ;
double progress = ( double ) displayIteration / m_maxIterations * 100 ;
double progress = ( double ) displayIteration / m_maxIterations * 100 ;
progressBar - > setFormat ( QString ( " %1% " ) . arg ( progress , 0 , ' f ' , 1 ) ) ;
progressBar - > setFormat ( QString ( " %1% " ) . arg ( progress , 0 , ' f ' , 1 ) ) ;
currentIterationValue - > setText ( QString : : number ( displayIteration ) ) ;
currentIterationValue - > setText ( QString ( " %1 / %2 " ) . arg ( displayIteration ) . arg ( m_maxIterations ) ) ;
}
}
currentComfortValue - > setText ( formatScientific ( fitness ) ) ;
currentComfortValue - > setText ( formatScientific ( fitness ) ) ;
@ -713,8 +867,8 @@ void nmWxAutomaticfittingStart::onFittingProgress(int iteration, double fitness)
if ( ! m_autoFitterLM ) addLogMessage ( tr ( " Better solution found: %1 " ) . arg ( formatScientific ( fitness ) ) ) ;
if ( ! m_autoFitterLM ) addLogMessage ( tr ( " Better solution found: %1 " ) . arg ( formatScientific ( fitness ) ) ) ;
// 更新参数 表格
// 更新参数 值。
updateParameter Table ( ) ;
updateParameter Values ( ) ;
} else {
} else {
bestComfortValue - > setStyleSheet ( " QLabel { color: black; } " ) ;
bestComfortValue - > setStyleSheet ( " QLabel { color: black; } " ) ;
}
}
@ -724,11 +878,20 @@ void nmWxAutomaticfittingStart::onFittingFinished(bool success, const QString& m
{
{
m_isFinished = true ;
m_isFinished = true ;
m_isFinalizing = false ;
m_isFinalizing = false ;
stateBadge - > setText ( success ? tr ( " Fitting ended " ) : tr ( " Fitting failed " ) ) ;
stateBadge - > setStyleSheet ( success
? " QLabel { color: #28765f; background: #edf7f2; } "
: " QLabel { color: #a04438; background: #fff0ed; } " ) ;
const QString algorithmName = m_algorithmName ;
const QString algorithmName = m_algorithmName ;
// 更新状态
// 更新状态
if ( success ) {
if ( m_autoFitterLM ) {
stageStatus - > setText ( success ? tr ( " Fitting ended " ) : tr ( " Fitting failed " ) ) ;
// 完成区直接读取优化器数值,失败评价显示占位符,不暴露惩罚值。
updateCurrentError ( m_autoFitterLM - > getBestFitness ( ) ) ;
stageStatus - > hide ( ) ;
} else if ( success ) {
progressBar - > setValue ( m_maxIterations ) ;
progressBar - > setValue ( m_maxIterations ) ;
// 区分正常完成和用户停止
// 区分正常完成和用户停止
@ -781,8 +944,8 @@ void nmWxAutomaticfittingStart::onFittingFinished(bool success, const QString& m
disconnect ( stopButton , SIGNAL ( clicked ( ) ) , this , SLOT ( onStopButtonClicked ( ) ) ) ;
disconnect ( stopButton , SIGNAL ( clicked ( ) ) , this , SLOT ( onStopButtonClicked ( ) ) ) ;
connect ( stopButton , SIGNAL ( clicked ( ) ) , this , SLOT ( close ( ) ) ) ;
connect ( stopButton , SIGNAL ( clicked ( ) ) , this , SLOT ( close ( ) ) ) ;
// 最终更新参数表格
// 同步最终参数值。
updateParameter Table ( ) ;
updateParameter Values ( ) ;
// 添加完成时间戳
// 添加完成时间戳
QDateTime endTime = QDateTime : : currentDateTime ( ) ;
QDateTime endTime = QDateTime : : currentDateTime ( ) ;
@ -803,7 +966,13 @@ void nmWxAutomaticfittingStart::onFittingFinished(bool success, const QString& m
// LM 的调用次数由优化器汇总,这里只在结束时显示一次总耗时。
// LM 的调用次数由优化器汇总,这里只在结束时显示一次总耗时。
if ( m_autoFitterLM ) {
if ( m_autoFitterLM ) {
addLogMessage ( tr ( " Total time: %1 min %2 s " ) . arg ( minutes ) . arg ( remainSec , 0 , ' f ' , 1 ) ) ;
// 不足一分钟只显示秒,窗口汇总和完成日志共用同一耗时文本。
const QString elapsed = minutes = = 0 ? tr ( " %1 s " ) . arg ( seconds , 0 , ' f ' , 1 )
: tr ( " %1 min %2 s " ) . arg ( minutes ) . arg ( remainSec , 0 , ' f ' , 1 ) ;
addLogMessage ( tr ( " Total time: %1 " ) . arg ( elapsed ) ) ;
runSummary - > setText ( tr ( " Solver calls: %1 | Total time: %2 " )
. arg ( m_autoFitterLM - > getSolverCallCount ( ) ) . arg ( elapsed ) ) ;
runSummary - > show ( ) ;
} else {
} else {
addLogMessage ( tr ( " Total fitting time: %1 s (%2 min %3 s), total solver calls: %4 " )
addLogMessage ( tr ( " Total fitting time: %1 s (%2 min %3 s), total solver calls: %4 " )
. arg ( seconds , 0 , ' f ' , 2 ) . arg ( minutes ) . arg ( remainSec , 0 , ' f ' , 2 ) . arg ( totalEvaluations ) ) ;
. arg ( seconds , 0 , ' f ' , 2 ) . arg ( minutes ) . arg ( remainSec , 0 , ' f ' , 2 ) . arg ( totalEvaluations ) ) ;
@ -816,6 +985,8 @@ void nmWxAutomaticfittingStart::onFinalizingStarted()
{
{
// 最终完整求解负责生成正式快照,此阶段不能再次停止或关闭进度窗口。
// 最终完整求解负责生成正式快照,此阶段不能再次停止或关闭进度窗口。
m_isFinalizing = true ;
m_isFinalizing = true ;
stateBadge - > setText ( tr ( " Finalizing... " ) ) ;
if ( m_autoFitterLM ) stageStatus - > setText ( tr ( " Generating final result... " ) ) ;
stopButton - > setEnabled ( false ) ;
stopButton - > setEnabled ( false ) ;
stopButton - > setText ( tr ( " Finalizing... " ) ) ;
stopButton - > setText ( tr ( " Finalizing... " ) ) ;
addLogMessage ( tr ( " Generating the final result with the current best parameters... " ) ) ;
addLogMessage ( tr ( " Generating the final result with the current best parameters... " ) ) ;
@ -837,6 +1008,8 @@ void nmWxAutomaticfittingStart::onStopButtonClicked()
// 先锁定按钮,等优化循环退出后由 finalizingStarted() 切换到最终求解状态。
// 先锁定按钮,等优化循环退出后由 finalizingStarted() 切换到最终求解状态。
stopButton - > setEnabled ( false ) ;
stopButton - > setEnabled ( false ) ;
stopButton - > setText ( tr ( " Stopping... " ) ) ;
stopButton - > setText ( tr ( " Stopping... " ) ) ;
stateBadge - > setText ( tr ( " Stopping... " ) ) ;
if ( m_autoFitterLM ) stageStatus - > setText ( tr ( " Stopping... " ) ) ;
if ( m_autoFitterPSO ) {
if ( m_autoFitterPSO ) {
m_autoFitterPSO - > stopFitting ( ) ;
m_autoFitterPSO - > stopFitting ( ) ;
} else if ( m_autoFitterLM ) {
} else if ( m_autoFitterLM ) {
@ -847,40 +1020,27 @@ void nmWxAutomaticfittingStart::onStopButtonClicked()
}
}
}
}
void nmWxAutomaticfittingStart : : updateParameter Table ( )
void nmWxAutomaticfittingStart : : updateParameter Values ( )
{
{
// 设置表格行数
// 使用当前已接受参数,普通数值优先显示十进制,极小数仍保留有效位。
tableWidget - > setRowCount ( m_selectedParameters . size ( ) ) ;
const QVector < double > values = m_autoFitterLM ? m_autoFitterLM - > getBestSolution ( )
: ( m_autoFitterPSO ? m_autoFitterPSO - > getBestSolution ( ) : QVector < double > ( ) ) ;
// 更新表格内容
for ( int i = 0 ; i < parameterValues . size ( ) ; + + i ) {
for ( int i = 0 ; i < m_selectedParameters . size ( ) ; + + i ) {
parameterValues [ i ] - > setText ( i < values . size ( ) ? QString : : number ( values [ i ] , ' g ' , 6 ) : " -- " ) ;
// 参数名
parameterValues [ i ] - > setToolTip ( i < values . size ( ) ? QString : : number ( values [ i ] , ' g ' , 15 ) : QString ( ) ) ;
QTableWidgetItem * nameItem = new QTableWidgetItem ( m_selectedParameters . at ( i ) ) ;
nameItem - > setFlags ( Qt : : ItemIsEnabled | Qt : : ItemIsSelectable ) ;
tableWidget - > setItem ( i , 0 , nameItem ) ;
// 最优参数值
QString valueText = " N/A " ;
if ( m_autoFitterPSO ) {
QVector < double > bestSolution = m_autoFitterPSO - > getBestSolution ( ) ;
if ( i < bestSolution . size ( ) ) {
valueText = formatScientific ( bestSolution [ i ] ) ;
}
} else if ( m_autoFitterLM ) {
QVector < double > bestSolution = m_autoFitterLM - > getBestSolution ( ) ;
if ( i < bestSolution . size ( ) ) {
valueText = formatScientific ( bestSolution [ i ] ) ;
}
}
QTableWidgetItem * valueItem = new QTableWidgetItem ( valueText ) ;
valueItem - > setFlags ( Qt : : ItemIsEnabled | Qt : : ItemIsSelectable ) ;
valueItem - > setTextAlignment ( Qt : : AlignRight | Qt : : AlignVCenter ) ;
tableWidget - > setItem ( i , 1 , valueItem ) ;
}
}
}
}
void nmWxAutomaticfittingStart : : updateCurrentError ( double fitness )
{
// 仅展示当前已接受参数对应的总误差,未获得有效结果时显示占位符。
const QString value = nmAutoFitChartIsFinite ( fitness ) & & fitness > = 0.0 & & fitness < 1.0e9
? QString : : number ( fitness , ' f ' , 6 ) : " -- " ;
resultSummary - > setText ( tr ( " Current error: %1 " )
. arg ( QString ( " <span style= \" color:#233247; font-weight:500; \" >%1</span> " ) . arg ( value ) ) ) ;
resultSummary - > show ( ) ;
}
void nmWxAutomaticfittingStart : : addLogMessage ( const QString & message )
void nmWxAutomaticfittingStart : : addLogMessage ( const QString & message )
{
{
// 获取滚动条
// 获取滚动条
@ -957,4 +1117,9 @@ void nmWxAutomaticfittingStart::onBestCurveUpdated(QVector<QVector<double> > tar
}
}
curveChart - > setBestLogLogData ( bestData , iteration , fitness ) ;
curveChart - > setBestLogLogData ( bestData , iteration , fitness ) ;
// 形状改善时总误差可能上升,参数值仍须同步到当前已接受曲线。
if ( m_autoFitterLM ) {
updateParameterValues ( ) ;
updateCurrentError ( fitness ) ;
}
}
}