diff --git a/Src/nmNum/nmSubWxs/nmWxForecast.cpp b/Src/nmNum/nmSubWxs/nmWxForecast.cpp index 59ceb057..5ee21081 100644 --- a/Src/nmNum/nmSubWxs/nmWxForecast.cpp +++ b/Src/nmNum/nmSubWxs/nmWxForecast.cpp @@ -4,12 +4,14 @@ #include #include #include +#include #include #include #include #include "nmCalculationDllPebiSolverTask.h" #include "nmGUIComponentLineEdit.h" #include "nmPebiResultSnapshot.h" +#include "ZxBaseUtil.h" nmWxForecast::nmWxForecast(QWidget *parent, nmDataAnalyzeManager* manager) : iDlgBase(parent) @@ -34,7 +36,8 @@ nmWxForecast::nmWxForecast(QWidget *parent, nmDataAnalyzeManager* manager) , m_extEmpty(nullptr) { setWindowTitle(tr("Forecast")); - setFixedSize(520, 560); + resize(560, 560); + setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); // 关闭时只隐藏,所属设计面板复用同一个输入窗口。 setAttribute(Qt::WA_DeleteOnClose, false); @@ -132,11 +135,16 @@ void nmWxForecast::saveDataToManager() void nmWxForecast::setupUI() { + // 与储层参数窗口统一边距,表格随窗口大小扩展。 m_mainLayout = new QVBoxLayout(this); + m_mainLayout->setContentsMargins(12, 10, 12, 0); + m_mainLayout->setSpacing(8); // ========== Forecast options ========== m_forecastOptionsGroup = new QGroupBox(tr("Forecast options"), this); m_forecastOptionsLayout = new QVBoxLayout(m_forecastOptionsGroup); + m_forecastOptionsLayout->setContentsMargins(10, 10, 10, 10); + m_forecastOptionsLayout->setSpacing(8); m_constantPressureRadio = new QRadioButton(tr("Constant pressure"), this); m_decliningPressureRadio = new QRadioButton(tr("Declining pressure (ramp)"), this); @@ -158,10 +166,14 @@ void nmWxForecast::setupUI() m_usePastHistoryCheck->setEnabled(false); m_surfacePressuresCheck->setEnabled(false); - m_forecastOptionsLayout->addWidget(m_constantPressureRadio); - m_forecastOptionsLayout->addWidget(m_decliningPressureRadio); - m_forecastOptionsLayout->addWidget(m_multiplePressuresRadio); - m_forecastOptionsLayout->addWidget(m_multipleRatesRadio); + QGridLayout* optionsLayout = new QGridLayout(); + optionsLayout->setHorizontalSpacing(16); + optionsLayout->setVerticalSpacing(8); + optionsLayout->addWidget(m_constantPressureRadio, 0, 0); + optionsLayout->addWidget(m_decliningPressureRadio, 0, 1); + optionsLayout->addWidget(m_multiplePressuresRadio, 1, 0); + optionsLayout->addWidget(m_multipleRatesRadio, 1, 1); + m_forecastOptionsLayout->addLayout(optionsLayout); QHBoxLayout *checkBoxLayout = new QHBoxLayout(); checkBoxLayout->addWidget(m_usePastHistoryCheck); @@ -172,11 +184,12 @@ void nmWxForecast::setupUI() // ========== Parameters ========== m_parametersGroup = new QGroupBox(tr("Parameters"), this); QVBoxLayout *parametersOuterLayout = new QVBoxLayout(m_parametersGroup); - parametersOuterLayout->setContentsMargins(6, 6, 6, 6); + parametersOuterLayout->setContentsMargins(10, 10, 10, 10); // 基础区 QWidget *baseWidget = new QWidget(this); m_parametersLayout = new QGridLayout(baseWidget); + m_parametersLayout->setContentsMargins(0, 0, 0, 0); m_parametersLayout->setHorizontalSpacing(8); m_parametersLayout->setVerticalSpacing(8); m_parametersLayout->setColumnStretch(0, 0); // 复选框列 @@ -184,11 +197,6 @@ void nmWxForecast::setupUI() int row = 0; - // 1. 创建一个“占位符” (strut),用于永久撑开第0列 - QWidget* column0Strut = new QWidget(this); - // 2. 将占位符添加到 (row 0, col 0) - m_parametersLayout->addWidget(column0Strut, row, 0); - // (row 0) Initial pressure ConstantPressure& constantPressureData = m_forecastData.getConstantPressureData(); m_initialPressureComponent = new nmGUIComponentLineEdit( @@ -196,7 +204,23 @@ void nmWxForecast::setupUI() true, this ); - m_parametersLayout->addWidget(m_initialPressureComponent, row, 1); + // 标签按内容占宽,数值和单位按储层参数页的比例铺满剩余空间。 + QLabel* pressureLabel = m_initialPressureComponent->findChild(); + // 先解除通用控件的 200 像素标签限制,再由布局按实际文字宽度分配。 + pressureLabel->setMinimumWidth(0); + pressureLabel->setMaximumWidth(QWIDGETSIZE_MAX); + pressureLabel->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Fixed); + QLineEdit* pressureEdit = m_initialPressureComponent->findChild(); + QComboBox* pressureUnit = m_initialPressureComponent->findChild(); + pressureEdit->setMinimumWidth(140); + pressureEdit->setMaximumWidth(QWIDGETSIZE_MAX); + pressureUnit->setMinimumWidth(86); + pressureUnit->setMaximumWidth(QWIDGETSIZE_MAX); + QHBoxLayout* pressureLayout = static_cast(m_initialPressureComponent->layout()); + delete pressureLayout->takeAt(1); // 移除标签后的弹性留白。 + pressureLayout->setStretchFactor(pressureEdit, 8); + pressureLayout->setStretchFactor(pressureUnit, 5); + m_parametersLayout->addWidget(m_initialPressureComponent, row, 0, 1, 2); row++; // (row 1) Abandonment rate @@ -231,10 +255,6 @@ void nmWxForecast::setupUI() m_parametersLayout->addWidget(m_forecastDurationComponent, row, 1); row++; - // 设置占位符的固定宽度,使其等于复选框的宽度 - int chkBoxWidth = m_abandonmentRateCheck->minimumSizeHint().width(); - column0Strut->setFixedWidth(chkBoxWidth); - // (row 4) Producing pressure m_producingPressureComponent = new nmGUIComponentLineEdit(&m_forecastData.getConstantPressureData().getProducingPressure(), true, this); m_parametersLayout->addWidget(m_producingPressureComponent, row, 1); @@ -265,15 +285,18 @@ void nmWxForecast::setupUI() m_extStackedWidget->addWidget(m_extMultiP); // 页面 2 m_extStackedWidget->addWidget(m_extMultiR); // 页面 3 - // --- 4. 将 QStackedWidget 添加到布局的固定位置 (row 5) --- - m_parametersLayout->addWidget(m_extStackedWidget, row, 1); - row++; // row 变为 6 - parametersOuterLayout->addWidget(baseWidget); - //parametersOuterLayout->addWidget(m_extStackedWidget); + + // 制度表格单独分组,占用参数区下方的可用空间。 + QGroupBox* scheduleGroup = new QGroupBox(tr("Multiple rates"), this); + QVBoxLayout* scheduleLayout = new QVBoxLayout(scheduleGroup); + scheduleLayout->setContentsMargins(10, 10, 10, 10); + scheduleLayout->addWidget(m_extStackedWidget); // ========== Buttons ========== m_buttonLayout = new QHBoxLayout(); + m_buttonLayout->setContentsMargins(4, 5, 4, 5); + m_buttonLayout->setSpacing(8); m_loadDataButton = new QPushButton(tr("Load data"), this); m_generateButton = new QPushButton(tr("Generate"), this); // 只有一张预测结果图,直接打开已有结果,不重新求解。 @@ -281,6 +304,8 @@ void nmWxForecast::setupUI() m_resultPlotButton->setObjectName("nmForecastResultPlots"); m_cancelButton = new QPushButton(tr("Cancel"), this); m_loadDataButton->setEnabled(false); + m_generateButton->setIcon(zxLoadIcon("OK")); + m_cancelButton->setIcon(zxLoadIcon("Cancel")); m_buttonLayout->addWidget(m_loadDataButton); m_buttonLayout->addStretch(); @@ -291,12 +316,11 @@ void nmWxForecast::setupUI() // ========== Main ========== m_mainLayout->addWidget(m_forecastOptionsGroup); m_mainLayout->addWidget(m_parametersGroup); - m_mainLayout->addStretch(); + m_mainLayout->addWidget(scheduleGroup, 1); m_mainLayout->addLayout(m_buttonLayout); // 收集所有组件 QList allComponents; - allComponents.append(m_initialPressureComponent); allComponents.append(m_abandonmentRateComponent); allComponents.append(m_maximumRateComponent); allComponents.append(m_forecastDurationComponent); @@ -643,6 +667,10 @@ void nmWxForecast::updateParametersForOption() const nmDataForecast::ForecastOption option = m_forecastData.getForecastOption(); + // 隐藏不适用的整行,避免多段产量模式留下空白占位。 + m_abandonmentStack->setVisible(option != nmDataForecast::MultipleRatesOption); + m_maximumStack->setVisible(option != nmDataForecast::MultipleRatesOption); + // 默认显示所有基本组件 if (m_abandonmentRateCheck) m_abandonmentRateCheck->setVisible(true); if (m_abandonmentStack) m_abandonmentStack->setCurrentIndex(0);