diff --git a/Include/nmNum/nmSubWxs/nmWxAutomaticFittingStart.h b/Include/nmNum/nmSubWxs/nmWxAutomaticFittingStart.h index e09b291f..1c8dce13 100644 --- a/Include/nmNum/nmSubWxs/nmWxAutomaticFittingStart.h +++ b/Include/nmNum/nmSubWxs/nmWxAutomaticFittingStart.h @@ -29,6 +29,7 @@ class nmCalculationAutoFitLM; class QPainter; class QColor; class QPaintEvent; +class QScrollArea; class nmAutomaticFittingCurveChart : public QWidget { @@ -104,11 +105,13 @@ public: protected: void closeEvent(QCloseEvent *event); + bool eventFilter(QObject* watched, QEvent* event); private: void setupUI(); void setupParameterArea(); void setupParameterStrip(); + void updateParameterAreaHeight(); void setupChartArea(); void setupLogArea(); void setupControlArea(); @@ -137,8 +140,10 @@ private: QLabel* targetWellValue; QLabel* algorithmTypeValue; - // 曲线和日志下方的整行参数,名称和单位在上、数值在下,用竖线分隔。 + // 参数每行最多六个,可见两行,其余通过垂直滚动查看。 QWidget* parameterStrip; + QScrollArea* parameterScrollArea; + QWidget* parameterContent; QGridLayout* parameterLayout; QVector parameterValues; diff --git a/Src/nmNum/nmSubWxs/nmWxAutomaticFittingStart.cpp b/Src/nmNum/nmSubWxs/nmWxAutomaticFittingStart.cpp index f220d974..9b001382 100644 --- a/Src/nmNum/nmSubWxs/nmWxAutomaticFittingStart.cpp +++ b/Src/nmNum/nmSubWxs/nmWxAutomaticFittingStart.cpp @@ -5,6 +5,8 @@ #include #include #include +#include +#include #include #include #include @@ -408,11 +410,12 @@ nmWxAutomaticfittingStart::nmWxAutomaticfittingStart(QWidget *parent) 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); + return QSize(qMin(1440, available.width() * 65 / 100), + qMin(820, available.height() * 50 / 100)); } nmWxAutomaticfittingStart::~nmWxAutomaticfittingStart() @@ -431,6 +434,7 @@ void nmWxAutomaticfittingStart::setupUI() "#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#parameterContent { background: #ffffff; }" "#autoFittingProgress QWidget#parameterSeparator { background: #e3e8ef; }" "#autoFittingProgress QLabel#parameterName { font-size: 12px; }" "#autoFittingProgress QLabel#parameterValue { color: #233247; font-size: 18px; font-weight: 500; }" @@ -545,16 +549,68 @@ void nmWxAutomaticfittingStart::setupParameterArea() void nmWxAutomaticfittingStart::setupParameterStrip() { - // 参数独占曲线和日志下方的整行,横向均分空间,不保留尾部空白。 + // 标题固定,参数网格放入滚动区,避免参数数量撑大整个窗口。 parameterStrip = new QWidget(this); parameterStrip->setObjectName("parameterStrip"); parameterStrip->setAttribute(Qt::WA_StyledBackground, true); - parameterStrip->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); - // 标题与参数共用网格,竖线跨越两行,上下留白均为 4 像素。 - parameterLayout = new QGridLayout(parameterStrip); - parameterLayout->setContentsMargins(22, 4, 22, 4); + parameterStrip->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); + QVBoxLayout* stripLayout = new QVBoxLayout(parameterStrip); + stripLayout->setContentsMargins(22, 4, 22, 4); + stripLayout->setSpacing(2); + QLabel* heading = new QLabel(tr("Current parameters"), parameterStrip); + heading->setObjectName("sectionHeading"); + stripLayout->addWidget(heading); + parameterScrollArea = new QScrollArea(parameterStrip); + parameterScrollArea->setFrameShape(QFrame::NoFrame); + parameterScrollArea->setWidgetResizable(true); + parameterScrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + parameterScrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); + parameterContent = new QWidget; + parameterContent->setObjectName("parameterContent"); + parameterContent->setAttribute(Qt::WA_StyledBackground, true); + parameterLayout = new QGridLayout(parameterContent); + parameterLayout->setContentsMargins(0, 0, 0, 0); parameterLayout->setHorizontalSpacing(0); - parameterLayout->setVerticalSpacing(2); + parameterLayout->setVerticalSpacing(8); + parameterLayout->setAlignment(Qt::AlignTop); + parameterScrollArea->setWidget(parameterContent); + stripLayout->addWidget(parameterScrollArea); + parameterScrollArea->viewport()->installEventFilter(this); + parameterStrip->hide(); +} + +bool nmWxAutomaticfittingStart::eventFilter(QObject* watched, QEvent* event) +{ + // 按滚动区的实际宽度重新计算换行高度,窗口缩放后仍只显示两行。 + if(watched == parameterScrollArea->viewport() && event->type() == QEvent::Resize) { + updateParameterAreaHeight(); + } + return iDlgBase::eventFilter(watched, event); +} + +void nmWxAutomaticfittingStart::updateParameterAreaHeight() +{ + if(parameterValues.isEmpty()) return; + const int columns = qMin(6, parameterValues.size()); + const int rows = (parameterValues.size() + 5) / 6; + const int scrollWidth = rows > 2 + ? parameterScrollArea->style()->pixelMetric(QStyle::PM_ScrollBarExtent) : 0; + const int cellWidth = qMax(1, + (parameterScrollArea->width() - scrollWidth - (columns - 1)) / columns); + int rowHeight = 0; + foreach(QLabel* value, parameterValues) { + QLayout* layout = value->parentWidget()->layout(); + rowHeight = qMax(rowHeight, qMax(layout->totalMinimumSize().height(), + layout->totalHeightForWidth(cellWidth))); + } + // 所有行使用相同高度,使第十三个参数开始完整地位于可滚动区域。 + foreach(QLabel* value, parameterValues) value->parentWidget()->setFixedHeight(rowHeight); + for(int row = 0; row < rows; ++row) parameterLayout->setRowMinimumHeight(row, rowHeight); + const int spacing = parameterLayout->verticalSpacing(); + parameterContent->setMinimumHeight(rows * rowHeight + (rows - 1) * spacing); + const int visibleRows = qMin(2, rows); + parameterScrollArea->setFixedHeight(visibleRows * rowHeight + (visibleRows - 1) * spacing); + parameterScrollArea->verticalScrollBar()->setSingleStep(rowHeight + spacing); } void nmWxAutomaticfittingStart::setupChartArea() @@ -786,12 +842,15 @@ void nmWxAutomaticfittingStart::setSelectedParameters(const QStringList& paramet 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 row = 0; row < parameterLayout->rowCount(); ++row) { + parameterLayout->setRowMinimumHeight(row, 0); + } + parameterContent->setMinimumHeight(0); for(int i = 0; i < parameterNames.size(); ++i) { // 名称和单位在上、数值在下,相邻参数用细竖线分隔。 - QWidget* cell = new QWidget(parameterStrip); + const int row = i / 6; + const int column = i % 6; + QWidget* cell = new QWidget(parameterContent); cell->setAttribute(Qt::WA_StyledBackground, true); QVBoxLayout* cellLayout = new QVBoxLayout(cell); cellLayout->setContentsMargins(12, 0, 12, 0); @@ -800,22 +859,24 @@ void nmWxAutomaticfittingStart::setSelectedParameters(const QStringList& paramet QLabel* name = new QLabel(parameterNames[i] + (unit.isEmpty() ? QString() : " / " + unit), cell); name->setObjectName("parameterName"); name->setWordWrap(true); + name->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Preferred); name->setAlignment(Qt::AlignCenter); QLabel* value = new QLabel("--", cell); value->setObjectName("parameterValue"); value->setAlignment(Qt::AlignCenter); + value->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Preferred); 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) { + parameterLayout->addWidget(cell, row, column * 2); + parameterLayout->setColumnStretch(column * 2, 1); + if(column > 0) { // 分隔线独立于参数单元格,避免标题导致上下间距不一致。 - QWidget* separator = new QWidget(parameterStrip); + QWidget* separator = new QWidget(parameterContent); separator->setObjectName("parameterSeparator"); separator->setAttribute(Qt::WA_StyledBackground, true); separator->setFixedWidth(1); - parameterLayout->addWidget(separator, 0, i * 2 - 1, 2, 1); + parameterLayout->addWidget(separator, row, column * 2 - 1); } parameterValues.append(value); } @@ -823,6 +884,9 @@ void nmWxAutomaticfittingStart::setSelectedParameters(const QStringList& paramet // 立即显示当前已接受的参数值。 updateParameterValues(); + parameterContent->ensurePolished(); + updateParameterAreaHeight(); + parameterScrollArea->verticalScrollBar()->setValue(0); const QString algorithmName = m_algorithmName; if(!m_autoFitterLM) addLogMessage(tr("%1 selected parameters: %2").arg(algorithmName).arg(parameterNames.join(", ")));