#include "nmWxNumericalDesign.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include "nmWxIncludeOtherWells.h" #include "nmWxTimeDependentSkin.h" #include "nmWxAutomaticFitting.h" #include "nmWxParameterProperty.h" #include "nmWxForecast.h" #include "nmWxSensitive.h" #include "nmGUIComponentLineEdit.h" #include "ZxDataWell.h" #include "ZxDataProject.h" #include "zxSysUtils.h" #include "nmDataWellBase.h" #include "nmDataReservoir.h" #include "nmDataAnalyzeManager.h" #include "nmDataTimeStepSetting.h" #include "nmDataDiagnostic.h" nmWxNumericalDesign* nmWxNumericalDesign::s_pCurrentInstance = nullptr; static bool isNumericalDesignDebugOptionsVisible() { #ifdef QT_DEBUG return true; #endif return false; } nmWxNumericalDesign::nmWxNumericalDesign(QWidget *parent) : iDlgBase(parent) { // 设置当前实例为静态指针 s_pCurrentInstance = this; m_pResultWellGroup = nullptr; m_pResultWellCombo = nullptr; m_bFillingResultWellCombo = false; // 初始化图标路径 m_sIconDir = QCoreApplication::applicationDirPath(); m_sIconDir = m_sIconDir.section('/', 0, -2); // 获取上一级目录 m_sIconDir += "/Res/Icon/"; // 设置窗口的尺寸策略为可扩展 this->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); // 创建滚动区域 QScrollArea* pScrollArea = new QScrollArea(this); pScrollArea->setWidgetResizable(true); QWidget* pScrollWidget = new QWidget(); pScrollWidget->setObjectName("nmNumericalDesignScrollWidget"); pScrollWidget->setStyleSheet("#nmNumericalDesignScrollWidget { background-color: white; }"); QVBoxLayout* pScrollLayout = new QVBoxLayout(pScrollWidget); // 初始化所有UI组件 initMainOptionsGroup(); // 初始化主选项组 initResultWellGroup(); initOutputGroup(); // 初始化输出组 (新) initAdvancedGroup(); // 初始化高级组 (新) initTimeSteppingGroup(); // 初始化时间步进组 initNumericalSettingsGroup(); // 初始化数值设置组 (新) initButton(); // 初始化生成按钮 // 将各个组添加到滚动区域的布局中 pScrollLayout->addWidget(m_pMainOptionsGroup); pScrollLayout->addWidget(m_pResultWellGroup); pScrollLayout->addWidget(m_pOutputGroup); pScrollLayout->addWidget(m_pAdvancedGroup); pScrollLayout->addWidget(m_pTimeSteppingGroup); pScrollLayout->addWidget(m_pNumericalSettingsGroup); // 新的数值设置组 pScrollLayout->addStretch(); // 添加拉伸器,使内容靠上 pScrollWidget->setLayout(pScrollLayout); // 设置滚动容器的布局 pScrollArea->setWidget(pScrollWidget); // 将滚动容器设置给滚动区域 // 设置主布局并添加滚动区域 m_pMainLayout = new QVBoxLayout(this); // 窗口的主布局 m_pMainLayout->addWidget(pScrollArea); // 将滚动区域添加到主布局 m_pMainLayout->addLayout(m_pGenerateLayout); // 将生成按钮布局添加到主布局底部 updateUiFromData(); // 更新时间步进组的组件值 // 设置信号槽连接 setupConnections(); //对于没有功能的组件,release下隐藏,debug下显示 bool bDebugOptionsVisible = isNumericalDesignDebugOptionsVisible(); m_pImposePiCheck->setVisible(bDebugOptionsVisible); m_pShowAveragePressureCheck->setVisible(bDebugOptionsVisible); m_pOutputGroup->setVisible(bDebugOptionsVisible); m_pUseWellIntakeCheck->setVisible(bDebugOptionsVisible); m_pRedefineKrPcCheck->setVisible(bDebugOptionsVisible); m_pRedefineKrPcIconButton->setVisible(bDebugOptionsVisible); m_pApplyUnconsolidationCheck->setVisible(bDebugOptionsVisible); m_pApplyUnconsolidationIconButton->setVisible(bDebugOptionsVisible); m_pUseDFNCheck->setVisible(bDebugOptionsVisible); m_pNumericalSettingsGroup->setVisible(bDebugOptionsVisible); m_pForecastBtn->setVisible(bDebugOptionsVisible); m_pSensitiveBtn->setVisible(bDebugOptionsVisible); } nmWxNumericalDesign::~nmWxNumericalDesign() { // 所有子控件将由Qt的父子对象机制自动删除 // 如果当前实例是静态指针指向的实例,则清空静态指针 if(s_pCurrentInstance == this) { s_pCurrentInstance = nullptr; } } // 外部刷新当前查看井下拉框 void nmWxNumericalDesign::notifyResultWellSelectorChanged(const QString& wellName) { if(s_pCurrentInstance == nullptr) { return; } s_pCurrentInstance->fillResultWellCombo(wellName); } // 初始化查看井结果切换控件 void nmWxNumericalDesign::initResultWellGroup() { m_pResultWellGroup = new QGroupBox(tr("View well result"), this); QGridLayout* pGridLayout = new QGridLayout(m_pResultWellGroup); QLabel* pCurrentWellLabel = new QLabel(tr("Current well:"), this); m_pResultWellCombo = new QComboBox(this); fillResultWellCombo(); pGridLayout->addWidget(pCurrentWellLabel, 0, 0, Qt::AlignLeft); pGridLayout->addWidget(m_pResultWellCombo, 0, 1); pGridLayout->setColumnStretch(0, 0); pGridLayout->setColumnStretch(1, 1); m_pResultWellGroup->setLayout(pGridLayout); m_pResultWellGroup->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); } // 按参与计算井刷新下拉框 void nmWxNumericalDesign::fillResultWellCombo(const QString& selectedWellName) { if(m_pResultWellCombo == nullptr) { return; } nmDataAnalyzeManager* pManager = nmDataAnalyzeManager::getCurrentInstance(); m_bFillingResultWellCombo = true; m_pResultWellCombo->clear(); if(pManager == nullptr) { m_pResultWellCombo->setEnabled(false); m_bFillingResultWellCombo = false; return; } // 使用本次参与计算的井 QVector> vecWellsOrder = pManager->getCalculationWells(); for(int i = 0; i < vecWellsOrder.size(); ++i) { if(vecWellsOrder[i].first == NM_WELL_MODEL::Unknow_Well) { continue; } if(m_pResultWellCombo->findText(vecWellsOrder[i].second) < 0) { m_pResultWellCombo->addItem(vecWellsOrder[i].second); } } QString sCurrentWellName = selectedWellName; if(sCurrentWellName.isEmpty()) { nmDataWellBase* pCurrentWell = pManager->getCurWellData(); if(pCurrentWell != nullptr) { sCurrentWellName = pCurrentWell->getWellName(); } } // 未计算时没有结果井列表,先显示当前井,避免下拉框空白。 if(m_pResultWellCombo->count() == 0 && !sCurrentWellName.isEmpty()) { m_pResultWellCombo->addItem(sCurrentWellName); } int nIndex = m_pResultWellCombo->findText(sCurrentWellName); if(nIndex < 0 && m_pResultWellCombo->count() > 0) { nIndex = 0; } if(nIndex >= 0) { m_pResultWellCombo->setCurrentIndex(nIndex); } m_pResultWellCombo->setEnabled(m_pResultWellCombo->count() > 1); m_bFillingResultWellCombo = false; } void nmWxNumericalDesign::initMainOptionsGroup() { m_pMainOptionsGroup = new QGroupBox(tr("Main options"), this); QGridLayout* pGridLayout = new QGridLayout(m_pMainOptionsGroup); // 使用 QGridLayout // 第一行: Include other wells + Gear Icon (左侧), Reset from diagnostic (右侧) m_pIncludeOtherWellsCheck = new QCheckBox(tr("Include other wells"), this); m_pOptionsGearButton = new QPushButton(this); m_pOptionsGearButton->setIcon(QIcon(m_sIconDir + "NmAnalDesign1.png")); m_pOptionsGearButton->setIconSize(QSize(20, 20)); m_pOptionsGearButton->setFixedSize(22, 22); m_pOptionsGearButton->setEnabled(m_pIncludeOtherWellsCheck->isChecked()); m_pResetDiagnosticButton = new QPushButton(tr("Reset from diagnostic"), this); m_pResetDiagnosticButton->setFixedWidth(150); // 为左侧的复选框和齿轮创建一个QHBoxLayout,以便它们可以紧密排列 QHBoxLayout* pIncludeWellsLayout = new QHBoxLayout(); pIncludeWellsLayout->addWidget(m_pIncludeOtherWellsCheck); pIncludeWellsLayout->addWidget(m_pOptionsGearButton); pIncludeWellsLayout->addStretch(); // 将它们推到左侧 pGridLayout->addLayout(pIncludeWellsLayout, 0, 0, Qt::AlignLeft); // 第0行,第0列,左对齐 pGridLayout->addWidget(m_pResetDiagnosticButton, 0, 1, Qt::AlignLeft); // 第0行,第1列,左对齐 // 第二行: Impose pi (左侧), Reset from analytical (右侧) m_pImposePiCheck = new QCheckBox(tr("Impose pi"), this); m_pImposePiCheck->setChecked(true); // 默认选中 m_pResetAnalyticalButton = new QPushButton(tr("Reset from analytical"), this); m_pResetAnalyticalButton->setFixedWidth(150); pGridLayout->addWidget(m_pImposePiCheck, 1, 0, Qt::AlignLeft); // 第1行,第0列,左对齐 pGridLayout->addWidget(m_pResetAnalyticalButton, 1, 1, Qt::AlignLeft); // 第1行,第1列,左对齐 // 第三行: Show average pressure (左侧), 右侧留空 m_pShowAveragePressureCheck = new QCheckBox(tr("Show average pressure"), this); m_pShowAveragePressureCheck->setChecked(false); // 默认未选中 pGridLayout->addWidget(m_pShowAveragePressureCheck, 2, 0, Qt::AlignLeft); // 第2行,第0列,左对齐 pGridLayout->setColumnStretch(0, 0); pGridLayout->setColumnStretch(1, 1); m_pMainOptionsGroup->setLayout(pGridLayout); // 设置分组框布局 m_pMainOptionsGroup->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); } void nmWxNumericalDesign::initOutputGroup() { m_pOutputGroup = new QGroupBox(tr("Output"), this); QGridLayout* pGridLayout = new QGridLayout(m_pOutputGroup); // 设置网格的边距和间距,确保内容不会太贴近边缘 pGridLayout->setContentsMargins(10, 10, 10, 10); // 调整内边距 pGridLayout->setHorizontalSpacing(10); // 水平间距 pGridLayout->setVerticalSpacing(5); // 垂直间距 // 第一行: Output result fields (复选框) + Automatic (单选按钮) m_pOutputResultFieldsCheck = new QCheckBox(tr("Output result fields"), this); m_pOutputResultFieldsCheck->setChecked(true); // 默认选中 m_pOutputAutomaticRadio = new QRadioButton(tr("Automatic"), this); m_pOutputAutomaticRadio->setChecked(true); // 默认选中Automatic // 根据 m_pOutputResultFieldsCheck 的初始状态设置单选按钮的初始启用状态 bool isOutputChecked = m_pOutputResultFieldsCheck->isChecked(); m_pOutputAutomaticRadio->setEnabled(isOutputChecked); // // 将 Output result fields 放在第0行,第0列 pGridLayout->addWidget(m_pOutputResultFieldsCheck, 0, 0, Qt::AlignLeft); // 将 Automatic 放在第0行,第1列 pGridLayout->addWidget(m_pOutputAutomaticRadio, 0, 1, Qt::AlignLeft); // 第二行: Manual (单选按钮) 和 齿轮图标,挨在一起,并且整体在右边 m_pOutputManualRadio = new QRadioButton(tr("Manual"), this); m_pOutputManualIconButton = new QPushButton(this); m_pOutputManualIconButton->setIcon(QIcon(m_sIconDir + "NmAnalDesign1.png")); // 确认图标路径正确 m_pOutputManualIconButton->setIconSize(QSize(20, 20)); m_pOutputManualIconButton->setFixedSize(22, 22); // m_pOutputManualIconButton 的初始启用状态将由两个条件决定: // 1. m_pOutputResultFieldsCheck 是否被勾选 // 2. m_pOutputManualRadio 是否被选中 // 这里先根据 m_pOutputResultFieldsCheck 设置一个初始值,后续连接会完善逻辑 m_pOutputManualIconButton->setEnabled(isOutputChecked && m_pOutputManualRadio->isChecked()); // // 将 Manual 和 齿轮图标放在一个 QHBoxLayout 中,让它们挨在一起 QHBoxLayout* pManualAndIconButtonLayout = new QHBoxLayout(); pManualAndIconButtonLayout->addWidget(m_pOutputManualRadio); pManualAndIconButtonLayout->addWidget(m_pOutputManualIconButton); pManualAndIconButtonLayout->addStretch(); // 使它们紧靠在一起,并推到该布局的左侧 // 将包含 Manual 和图标的 QHBoxLayout 放在第1行,第1列,并右对齐 pGridLayout->addLayout(pManualAndIconButtonLayout, 1, 1, Qt::AlignRight); // 第三行: Output well drainage results (复选框) m_pOutputWellDrainageCheck = new QCheckBox(tr("Output well drainage results"), this); m_pOutputWellDrainageCheck->setChecked(false); // 默认未选中 m_pOutputWellDrainageCheck->setEnabled(isOutputChecked); // 初始状态也受主复选框控制 // 跨越所有列(0到1,共2列),左对齐 pGridLayout->addWidget(m_pOutputWellDrainageCheck, 2, 0, 1, 2, Qt::AlignLeft); // 设置列拉伸: // 第0列 (Output result fields): 不拉伸,只占其内容宽度 pGridLayout->setColumnStretch(0, 0); // 第1列 (Automatic / Manual & Icon group): 拉伸,以提供足够的空间并将右侧的 Manual & Icon group 推到右边 pGridLayout->setColumnStretch(1, 1); m_pOutputGroup->setLayout(pGridLayout); m_pOutputGroup->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); } void nmWxNumericalDesign::initAdvancedGroup() { m_pAdvancedGroup = new QGroupBox(tr("Advanced"), this); // 创建高级分组框 QVBoxLayout* pMainVLayout = new QVBoxLayout(m_pAdvancedGroup); // 高级组的垂直布局 // 时间相关复选框和关联的时钟图标按钮 QHBoxLayout* pTimeDependentLayout = new QHBoxLayout(); // 为时间相关复选框和图标创建水平布局 m_pTimeDependentCheck = new QCheckBox(tr("Time dependent"), this); // "时间相关"复选框 m_pTimeDependentCheck->setChecked(false); // 默认未选中 m_pTimeDependentIconButton = new QPushButton(this); // 时钟图标按钮 m_pTimeDependentIconButton->setIcon(QIcon(m_sIconDir + "NmAnalDesign3.png")); // 使用时钟图标 m_pTimeDependentIconButton->setIconSize(QSize(20, 20)); m_pTimeDependentIconButton->setFixedSize(22, 22); m_pTimeDependentIconButton->setEnabled(false); // 默认禁用,根据复选框状态启用 pTimeDependentLayout->addWidget(m_pTimeDependentCheck); // 添加复选框 pTimeDependentLayout->addWidget(m_pTimeDependentIconButton); // 添加图标按钮 pTimeDependentLayout->addStretch(); // 添加拉伸器,将它们推到左侧 pMainVLayout->addLayout(pTimeDependentLayout); // 将这个水平布局添加到主垂直布局 m_pUseWellIntakeCheck = new QCheckBox(tr("Use well intake"), this); // "使用井筒进水"复选框 m_pUseWellIntakeCheck->setChecked(false); // 默认未选中 pMainVLayout->addWidget(m_pUseWellIntakeCheck); // 添加到主垂直布局 QHBoxLayout* pRedefineKrPcLayout = new QHBoxLayout(); // "重新定义 KrPc"的水平布局 m_pRedefineKrPcCheck = new QCheckBox(tr("Redefine KrPc in hydraulic fractures"), this); // 复选框 m_pRedefineKrPcIconButton = new QPushButton(this); // 图标按钮 m_pRedefineKrPcIconButton->setIcon(QIcon(m_sIconDir + "KK.png")); // 根据图片,这个图标应该是曲线图 m_pRedefineKrPcIconButton->setIconSize(QSize(40, 40)); m_pRedefineKrPcIconButton->setFixedSize(42, 42); m_pRedefineKrPcIconButton->setEnabled(false); // 默认禁用 pRedefineKrPcLayout->addWidget(m_pRedefineKrPcCheck); pRedefineKrPcLayout->addWidget(m_pRedefineKrPcIconButton); pRedefineKrPcLayout->addStretch(); // 添加拉伸器 pMainVLayout->addLayout(pRedefineKrPcLayout); // 添加到主垂直布局 QHBoxLayout* pApplyUnconsolidationLayout = new QHBoxLayout(); // "应用未固结"的水平布局 m_pApplyUnconsolidationCheck = new QCheckBox(tr("Apply unconsolidation in hydraulic fractures"), this); // 复选框 m_pApplyUnconsolidationIconButton = new QPushButton(this); // 图标按钮 m_pApplyUnconsolidationIconButton->setIcon(QIcon(m_sIconDir + "SS.png")); // 根据图片,这个图标应该是方块压缩 m_pApplyUnconsolidationIconButton->setIconSize(QSize(47, 42)); m_pApplyUnconsolidationIconButton->setFixedSize(49, 44); m_pApplyUnconsolidationIconButton->setEnabled(false); // 默认禁用 pApplyUnconsolidationLayout->addWidget(m_pApplyUnconsolidationCheck); pApplyUnconsolidationLayout->addWidget(m_pApplyUnconsolidationIconButton); pApplyUnconsolidationLayout->addStretch(); // 添加拉伸器 pMainVLayout->addLayout(pApplyUnconsolidationLayout); // 添加到主垂直布局 m_pUseDFNCheck = new QCheckBox(tr("Use DFN"), this); // "使用 DFN"复选框 m_pUseDFNCheck->setChecked(false); // 默认未选中 pMainVLayout->addWidget(m_pUseDFNCheck); // 添加到主垂直布局 m_pAdvancedGroup->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); // 设置尺寸策略 } void nmWxNumericalDesign::initTimeSteppingGroup() { m_pTimeSteppingGroup = new QGroupBox(tr("Time stepping"), this); QVBoxLayout* pMainVLayout = new QVBoxLayout(m_pTimeSteppingGroup); // 获取数据对象 nmDataTimeStepSetting* pTimeStepSetting = nmDataAnalyzeManager::getCurrentInstance()->getTimeStep(); // 创建组件 m_pTimeGrowthExponentCom = new nmGUIComponentLineEdit(&pTimeStepSetting->getTimeGrowthExponent(), true); m_pDtMinCom = new nmGUIComponentLineEdit(&pTimeStepSetting->getMinDeltaTAttribute(), true); m_pDtMaxCom = new nmGUIComponentLineEdit(&pTimeStepSetting->getMaxDeltaTAttribute(), true); // 实时更新到数据模型 m_pTimeGrowthExponentCom->setIsRealTimeUpdateValue(true); m_pDtMinCom->setIsRealTimeUpdateValue(true); m_pDtMaxCom->setIsRealTimeUpdateValue(true); // 添加到布局 pMainVLayout->addWidget(m_pTimeGrowthExponentCom); pMainVLayout->addWidget(m_pDtMinCom); pMainVLayout->addWidget(m_pDtMaxCom); m_pTimeSteppingGroup->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); } //void nmWxNumericalDesign::initTimeSteppingGroup() //{ // m_pTimeSteppingGroup = new QGroupBox(tr("Time stepping"), this); // 创建时间步进分组框 // QVBoxLayout* pMainVLayout = new QVBoxLayout(m_pTimeSteppingGroup); // 时间步进组的垂直布局 // // // 第一行:Use coarse stepping away from extractions // QHBoxLayout* pCoarseSteppingLayout = new QHBoxLayout(); // 水平布局用于复选框 // m_pUseCoarseSteppingCheck = new QCheckBox(tr("Use coarse stepping away from extractions"), this); // 复选框 // pCoarseSteppingLayout->addWidget(m_pUseCoarseSteppingCheck); // pCoarseSteppingLayout->addStretch(); // 添加拉伸器,将复选框推到左侧 // pMainVLayout->addLayout(pCoarseSteppingLayout); // 将布局添加到主垂直布局 // // // 第二行:循环箭头图标 + Absolute / Elapsed + Time unit: hr (下拉框) // QHBoxLayout* pTimeRadioUnitLayout = new QHBoxLayout(); // 顶部单选按钮布局 // // // 循环箭头图标按钮 // m_pResetTimeStep = new QPushButton(this); // 新增的循环箭头图标按钮 // m_pResetTimeStep->setIcon(QIcon(m_sIconDir + "NmAnalDesign4.png")); // 假设图标名为 NmAnalDesign_refresh.png // m_pResetTimeStep->setIconSize(QSize(20, 20)); // m_pResetTimeStep->setFixedSize(22, 22); // // 按钮的启用状态可以根据实际逻辑来定,此处暂时默认启用 // // m_pAbsoluteRadio = new QRadioButton(tr("Absolute"), this); // "绝对"单选按钮 // m_pElapsedRadio = new QRadioButton(tr("Elapsed"), this); // "流逝"单选按钮 // // // 将 m_pTimeUnitLabelFixed 替换为 QComboBox // m_pTimeUnitComboBox = new QComboBox(this); // 时间单位下拉框 // // // 为了实现"没有框的下拉框"的视觉效果,可以尝试设置 QComboBox 的样式表 // // 这是一个可选的视觉优化,不影响功能 // m_pTimeUnitComboBox->setStyleSheet( // "QComboBox {" // " border: 0px;" // 移除边框 // " padding-right: 0px;" // 移除右侧内边距,使箭头更靠近文本 // "}" // "QComboBox::down-arrow {" // " image: url(none);" // 移除箭头图片 // "}" // "QComboBox::drop-down {" // " subcontrol-origin: padding;" // " subcontrol-position: top right;" // " width: 0px;" // 完全隐藏下拉按钮区域 // " border: 0px;" // "}" // ); // // pTimeRadioUnitLayout->addWidget(m_pResetTimeStep); // 添加循环箭头图标按钮 // pTimeRadioUnitLayout->addSpacing(10); // 增加间距以对齐其他元素 // pTimeRadioUnitLayout->addWidget(m_pAbsoluteRadio); // pTimeRadioUnitLayout->addWidget(m_pElapsedRadio); // pTimeRadioUnitLayout->addSpacing(20); // 单选按钮和时间单位之间的间距 // pTimeRadioUnitLayout->addWidget(new QLabel(tr("Time unit:"), this)); // 添加"Time unit:"标签 // pTimeRadioUnitLayout->addWidget(m_pTimeUnitComboBox); // 添加下拉框 // pTimeRadioUnitLayout->addStretch(); // 添加拉伸器 // pMainVLayout->addLayout(pTimeRadioUnitLayout); // 将布局添加到主垂直布局 // // //// 新增的"From..."行 // //QHBoxLayout* pFromHLayout = new QHBoxLayout(); // //QLabel* pFromLabel = new QLabel(tr("From..."), this); // //pFromLabel->setFixedWidth(90); // // //// 创建两个不同的输入框 // //m_pFromElapsedLineEdit = new QLineEdit(this); // //m_pFromElapsedLineEdit->setFixedWidth(137); // // //m_pFromAbsoluteDateTimeEdit = new QDateTimeEdit(this); // //m_pFromAbsoluteDateTimeEdit->setCalendarPopup(true); // //m_pFromAbsoluteDateTimeEdit->setDisplayFormat("yyyy-MM-dd hh:mm:ss"); // //m_pFromAbsoluteDateTimeEdit->setFixedWidth(137); // // //// 用 QStackedLayout 管理两个输入控件 // //m_pFromStackedLayout = new QStackedLayout(); // //m_pFromStackedLayout->addWidget(m_pFromElapsedLineEdit); // index 0 // //m_pFromStackedLayout->addWidget(m_pFromAbsoluteDateTimeEdit); // index 1 // // //pFromHLayout->addWidget(pFromLabel); // //pFromHLayout->addLayout(m_pFromStackedLayout); // 只放 stacked // //pFromHLayout->addStretch(); // //pMainVLayout->addLayout(pFromHLayout); // // //// "模拟直到..."行 // //QHBoxLayout* pSimulateUntilHLayout = new QHBoxLayout(); // //QLabel* pSimulateUntilLabel = new QLabel(tr("Simulate until..."), this); // //pSimulateUntilLabel->setFixedWidth(90); // // //// 创建两个不同的输入框 // //m_pSimulateUntilElapsedLineEdit = new QLineEdit(this); // //m_pSimulateUntilElapsedLineEdit->setFixedWidth(137); // // //m_pSimulateUntilAbsoluteDateTimeEdit = new QDateTimeEdit(this); // //m_pSimulateUntilAbsoluteDateTimeEdit->setCalendarPopup(true); // //m_pSimulateUntilAbsoluteDateTimeEdit->setDisplayFormat("yyyy-MM-dd hh:mm:ss"); // //m_pSimulateUntilAbsoluteDateTimeEdit->setFixedWidth(137); // // //m_pSimulateUntilStackedLayout = new QStackedLayout(); // //m_pSimulateUntilStackedLayout->addWidget(m_pSimulateUntilElapsedLineEdit); // index 0 // //m_pSimulateUntilStackedLayout->addWidget(m_pSimulateUntilAbsoluteDateTimeEdit); // index 1 // // //pSimulateUntilHLayout->addWidget(pSimulateUntilLabel); // //pSimulateUntilHLayout->addLayout(m_pSimulateUntilStackedLayout); // //pSimulateUntilHLayout->addStretch(); // //pMainVLayout->addLayout(pSimulateUntilHLayout); // // // 时间增长指数 // QHBoxLayout* pTimeGrowthLayout = new QHBoxLayout(); // QLabel* pTimeGrowthLabel = new QLabel(tr("Time growth exponent"), this); // pTimeGrowthLabel->setFixedWidth(90); // m_pTimeGrowthExponentLineEdit = new QLineEdit(this); // m_pTimeGrowthExponentLineEdit->setFixedWidth(137); // //m_pTimeGrowthExponentLineEdit->setText("1.05"); // 默认值 // pTimeGrowthLayout->addWidget(pTimeGrowthLabel); // pTimeGrowthLayout->addWidget(m_pTimeGrowthExponentLineEdit); // pTimeGrowthLayout->addStretch(); // pMainVLayout->addLayout(pTimeGrowthLayout); // // // Dt 最小值 // QHBoxLayout* pDtMinHLayout = new QHBoxLayout(); // QLabel* pDtMinLabel = new QLabel(tr("Dt min"), this); // pDtMinLabel->setFixedWidth(90); // m_pDtMinLineEdit = new QLineEdit(this); // m_pDtMinLineEdit->setFixedWidth(137); // pDtMinHLayout->addWidget(pDtMinLabel); // pDtMinHLayout->addWidget(m_pDtMinLineEdit); // pDtMinHLayout->addStretch(); // 添加拉伸器 // pMainVLayout->addLayout(pDtMinHLayout); // 添加到主垂直布局 // // // Dt 最大值 // QHBoxLayout* pDtMaxHLayout = new QHBoxLayout(); // QLabel* pDtMaxLabel = new QLabel(tr("Dt max"), this); // pDtMaxLabel->setFixedWidth(90); // m_pDtMaxLineEdit = new QLineEdit(this); // m_pDtMaxLineEdit->setFixedWidth(137); // m_pIgnoreCheck = new QCheckBox(tr("Ignore"), this); // "忽略"复选框 // // pDtMaxHLayout->addWidget(pDtMaxLabel); // pDtMaxHLayout->addWidget(m_pDtMaxLineEdit); // pDtMaxHLayout->addWidget(m_pIgnoreCheck); // pDtMaxHLayout->addStretch(); // 添加拉伸器 // pMainVLayout->addLayout(pDtMaxHLayout); // 添加到主垂直布局 // // m_pTimeSteppingGroup->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); // 设置尺寸策略 //} void nmWxNumericalDesign::initNumericalSettingsGroup() { m_pNumericalSettingsGroup = new QGroupBox(tr("Numerical settings"), this); // 创建数值设置分组框 QVBoxLayout* pMainVLayout = new QVBoxLayout(m_pNumericalSettingsGroup); // 主垂直布局,用于放置子布局 // 第一行:Use automatic settings 单选按钮 // 直接添加到主垂直布局 m_pUseAutomaticSettingsRadio = new QRadioButton(tr("Use automatic settings"), this); // "使用自动设置"单选按钮 m_pUseAutomaticSettingsRadio->setChecked(true); // 默认选中"使用自动设置" pMainVLayout->addWidget(m_pUseAutomaticSettingsRadio); // 第二行:Use custom settings 单选按钮 + 齿轮图标 QHBoxLayout* pCustomSettingsHLayout = new QHBoxLayout(); // 为第二行创建一个水平布局 m_pUseCustomSettingsRadio = new QRadioButton(tr("Use custom settings"), this); // "使用自定义设置"单选按钮 m_pCustomSettingsIconButton = new QPushButton(this); // 自定义设置旁边的图标按钮 m_pCustomSettingsIconButton->setIcon(QIcon(m_sIconDir + "NmAnalDesign1.png")); // 占位符图标 m_pCustomSettingsIconButton->setIconSize(QSize(20, 20)); m_pCustomSettingsIconButton->setFixedSize(22, 22); m_pCustomSettingsIconButton->setEnabled(false); // 默认禁用,当选择"使用自定义设置"时启用 // 这个值可以根据实际显示效果调整 pCustomSettingsHLayout->addWidget(m_pUseCustomSettingsRadio); pCustomSettingsHLayout->addWidget(m_pCustomSettingsIconButton); pCustomSettingsHLayout->addStretch(); // 添加拉伸器,确保按钮和图标靠左对齐 pMainVLayout->addLayout(pCustomSettingsHLayout); // 将第二行的水平布局添加到主垂直布局 m_pNumericalSettingsGroup->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); // 设置尺寸策略 } void nmWxNumericalDesign::initButton() { // 创建自动拟合按钮 m_pAutomaticfittingBtn = new QPushButton(tr("Automatic fitting"), this); m_pAutomaticfittingBtn->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); // 创建预测按钮 m_pForecastBtn = new QPushButton(tr("Forecast"), this); m_pForecastBtn->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); // 创建敏感性分析按钮 m_pSensitiveBtn = new QPushButton(tr("Sensitive"), this); m_pSensitiveBtn->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); // 创建右下角按钮 m_pGenerateButton = new QPushButton(tr("Generate"), this); // "生成"按钮 m_pGenerateButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); // 固定尺寸 // 创建按钮布局 m_pGenerateLayout = new QHBoxLayout(); // 水平布局 m_pGenerateLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum)); // 左侧添加拉伸器 m_pGenerateLayout->addWidget(m_pAutomaticfittingBtn); m_pGenerateLayout->addSpacing(10); m_pGenerateLayout->addWidget(m_pForecastBtn); m_pGenerateLayout->addSpacing(10); m_pGenerateLayout->addWidget(m_pSensitiveBtn); m_pGenerateLayout->addSpacing(10); m_pGenerateLayout->addWidget(m_pGenerateButton); } void nmWxNumericalDesign::setupConnections() { // 连接生成按钮的点击信号到槽函数 connect(m_pGenerateButton, SIGNAL(clicked()), this, SLOT(onGenerateClicked())); connect(m_pResultWellCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(onResultWellChanged(int))); // 主选项组连接 // 连接齿轮图标按钮的槽函数 connect(m_pOptionsGearButton, SIGNAL(clicked()), this, SLOT(onOptionsIconClicked())); connect(m_pAutomaticfittingBtn, SIGNAL(clicked()), this, SLOT(onAutomaticFittingClicked())); connect(m_pForecastBtn, SIGNAL(clicked()), this, SLOT(onForecastClicked())); connect(m_pSensitiveBtn, SIGNAL(clicked()), this, SLOT(onSensitiveClicked())); // 更新齿轮图标按钮的启用状态 connect(m_pIncludeOtherWellsCheck, SIGNAL(toggled(bool)), m_pOptionsGearButton, SLOT(setEnabled(bool))); connect(m_pResetDiagnosticButton, SIGNAL(clicked()), this, SLOT(onResetFromDiagnosticClicked())); // "从诊断复位"按钮连接 connect(m_pResetAnalyticalButton, SIGNAL(clicked()), this, SLOT(onResetFromAnalyticalClicked())); // "从解析复位"按钮连接 // 输出组连接 // 新增连接:m_pOutputResultFieldsCheck 控制其他相关组件的启用/禁用 connect(m_pOutputResultFieldsCheck, SIGNAL(toggled(bool)), this, SLOT(onOutputResultFieldsToggled(bool))); // connect(m_pOutputAutomaticRadio, SIGNAL(toggled(bool)), this, SLOT(onOutputResultFieldsAutomaticToggled(bool))); // "自动"单选按钮连接 connect(m_pOutputManualRadio, SIGNAL(toggled(bool)), this, SLOT(onOutputResultFieldsManualToggled(bool))); // "手动"单选按钮连接 connect(m_pOutputManualIconButton, SIGNAL(clicked()), this, SLOT(onManualOutputSettingsClicked())); // "手动"图标按钮连接 // 高级组连接 // 在 setupConnections() 中连接 pTimeDependentIconButton 的信号槽,或者在这里连接 connect(m_pTimeDependentCheck, SIGNAL(toggled(bool)), m_pTimeDependentIconButton, SLOT(setEnabled(bool))); connect(m_pTimeDependentCheck, SIGNAL(toggled(bool)), this, SLOT(onTimeDependentCheck(bool))); // 如果这个图标按钮有自己的点击逻辑,需要连接到槽函数 connect(m_pTimeDependentIconButton, SIGNAL(clicked()), this, SLOT(onTimeIconClicked())); // "重新定义 KrPc"图标按钮的启用状态取决于复选框 connect(m_pRedefineKrPcCheck, SIGNAL(toggled(bool)), m_pRedefineKrPcIconButton, SLOT(setEnabled(bool))); connect(m_pRedefineKrPcIconButton, SIGNAL(clicked()), this, SLOT(onRedefineKrPcIconClicked())); // 图标按钮点击连接 // "应用未固结"图标按钮的启用状态取决于复选框 connect(m_pApplyUnconsolidationCheck, SIGNAL(toggled(bool)), m_pApplyUnconsolidationIconButton, SLOT(setEnabled(bool))); connect(m_pApplyUnconsolidationIconButton, SIGNAL(clicked()), this, SLOT(onApplyUnconsolidationIconClicked())); // 图标按钮点击连接 // 时间步 // Dt max 和 Ignore 复选框的连接 //connect(m_pIgnoreCheck, SIGNAL(toggled(bool)), this, SLOT(onIgnoreCheckToggled(bool))); // 连接 m_pElapsedRadio 和 m_pAbsoluteRadio 的 toggled 信号 //connect(m_pAbsoluteRadio, SIGNAL(toggled(bool)), this, SLOT(onTimeReferenceSystemToggled(bool))); //connect(m_pElapsedRadio, SIGNAL(toggled(bool)), this, SLOT(onTimeReferenceSystemToggled(bool))); // "流逝"时间输入框的值改变时 //connect(m_pFromElapsedLineEdit, SIGNAL(editingFinished()), this, SLOT(onTimeSteppingUiChanged())); //connect(m_pSimulateUntilElapsedLineEdit, SIGNAL(editingFinished()), this, SLOT(onTimeSteppingUiChanged())); // "绝对"时间输入框的值改变时 //connect(m_pFromAbsoluteDateTimeEdit, SIGNAL(dateTimeChanged(const QDateTime&)), this, SLOT(onTimeSteppingUiChanged())); //connect(m_pSimulateUntilAbsoluteDateTimeEdit, SIGNAL(dateTimeChanged(const QDateTime&)), this, SLOT(onTimeSteppingUiChanged())); //connect(m_pTimeGrowthExponentLineEdit, SIGNAL(editingFinished()), this, SLOT(onTimeSteppingUiChanged())); // 其他时间步进组件的值改变时 //connect(m_pUseCoarseSteppingCheck, SIGNAL(toggled(bool)), this, SLOT(onTimeSteppingUiChanged())); //connect(m_pDtMinLineEdit, SIGNAL(editingFinished()), this, SLOT(onTimeSteppingUiChanged())); //connect(m_pDtMaxLineEdit, SIGNAL(editingFinished()), this, SLOT(onTimeSteppingUiChanged())); //connect(m_pIgnoreCheck, SIGNAL(toggled(bool)), this, SLOT(onTimeSteppingUiChanged())); // 时间单位下拉框 //connect(m_pTimeUnitComboBox, SIGNAL(currentIndexChanged(const QString&)), //this, SLOT(onTimeUnitChanged(const QString&))); // 重置时间步 //connect(m_pResetTimeStep, SIGNAL(clicked()), this, SLOT(onResetTimeStep())); // 数值设置组连接 // "自定义设置"图标按钮的启用状态取决于"使用自定义设置"单选按钮 connect(m_pUseCustomSettingsRadio, SIGNAL(toggled(bool)), m_pCustomSettingsIconButton, SLOT(setEnabled(bool))); connect(m_pCustomSettingsIconButton, SIGNAL(clicked()), this, SLOT(onCustomNumericalSettingsClicked())); // 图标按钮点击连接 } void nmWxNumericalDesign::onTimeDependentCheck(bool checked) { // 更新当前井的时间变表皮状态 nmDataWellBase* pCurrentWell = nmDataAnalyzeManager::getCurrentInstance()->getCurWellData(); if(pCurrentWell) { pCurrentWell->setTimeDependentSkin(checked); } } // 切换查看井后同步当前井,并刷新结果曲线 void nmWxNumericalDesign::onResultWellChanged(int index) { if(m_bFillingResultWellCombo || index < 0 || m_pResultWellCombo == nullptr) { return; } QString sWellName = m_pResultWellCombo->itemText(index); if(sWellName.isEmpty()) { return; } nmDataAnalyzeManager* pManager = nmDataAnalyzeManager::getCurrentInstance(); if(pManager != nullptr) { nmDataWellBase* pWellData = pManager->findWellByName(sWellName); if(pWellData != nullptr) { pManager->setCurWellData(pWellData); } } // 复用主窗口已有的井结果刷新逻辑 emit sigResultWellChanged(sWellName); } void nmWxNumericalDesign::onGenerateClicked() { updateDataFromUi(); nmDataTimeStepSetting* p = nmDataAnalyzeManager::getCurrentInstance()->getTimeStep(); if (!p) return; double minV = p->getMinDeltaTAttribute().getValue().toDouble(); double maxV = p->getMaxDeltaTAttribute().getValue().toDouble(); if (minV >= maxV) { QMessageBox::warning(this, tr("Invalid Range"), tr("Dt min must be less than Dt max.")); return; } emit sigGenerateClicked(); } void nmWxNumericalDesign::onResetFromDiagnosticClicked() { nmDataAnalyzeManager* pManager = nmDataAnalyzeManager::getCurrentInstance(); if(!pManager) { QMessageBox::warning(this, tr("Warning"), tr("No data manager available.")); return; } if(pManager->resetFromDiagnostic()) { // 通知参数面板更新显示 nmWxParameterProperty::notifyUpdateTable(); } else { QMessageBox::warning(this, tr("Warning"), tr("Failed to reset from diagnostic. Please check if log-log data is available.")); } } void nmWxNumericalDesign::onResetFromAnalyticalClicked() { nmDataAnalyzeManager* pManager = nmDataAnalyzeManager::getCurrentInstance(); if(!pManager) { QMessageBox::warning(this, tr("Warning"), tr("No data manager available.")); return; } if(pManager->resetFromAnalytical()) { // 通知参数面板更新显示 nmWxParameterProperty::notifyUpdateTable(); } else { QMessageBox::warning(this, tr("Warning"), tr("Failed to reset to analytical defaults.")); } } void nmWxNumericalDesign::onManualOutputSettingsClicked() { // 占位符:显示消息框 QMessageBox::information(this, tr("Output Settings"), tr("Manual output settings clicked.")); } void nmWxNumericalDesign::onRedefineKrPcIconClicked() { // 占位符:显示消息框 QMessageBox::information(this, tr("Advanced Settings"), tr("Redefine KrPc settings clicked.")); } void nmWxNumericalDesign::onApplyUnconsolidationIconClicked() { // 占位符:显示消息框 QMessageBox::information(this, tr("Advanced Settings"), tr("Apply unconsolidation settings clicked.")); } void nmWxNumericalDesign::onCustomNumericalSettingsClicked() { // 占位符:显示消息框 QMessageBox::information(this, tr("Numerical Settings"), tr("Custom numerical settings clicked.")); } // 针对高级组中的"时间相关"按钮的槽函数 void nmWxNumericalDesign::onTimeIconClicked() { nmWxTimeDependentSkin::showForCurrentWell(); } void nmWxNumericalDesign::onOutputResultFieldsAutomaticToggled(bool checked) { // 当"自动"单选按钮被选中时,禁用手动输出设置按钮 if(checked) { m_pOutputManualIconButton->setEnabled(false); } } void nmWxNumericalDesign::onOutputResultFieldsManualToggled(bool checked) { // 当"手动"单选按钮被选中时,启用手动输出设置按钮 if(checked) { m_pOutputManualIconButton->setEnabled(true); } } void nmWxNumericalDesign::onOptionsIconClicked() { nmWxIncludeOtherWells dlg(this); // 创建"包含其他井"对话框实例 if(dlg.exec() == QDialog::Accepted) { // 如果对话框被接受(点击了确定) // 获取用户选择的数据 QVector vecSelectedWells = dlg.getWellData(); QString sCurrentWell; nmDataWellBase* pCurrentWell = nmDataAnalyzeManager::getCurrentInstance()->getCurWellData(); if(pCurrentWell != nullptr) { sCurrentWell = pCurrentWell->getWellName(); } ZxDataObjectList wellList; if(zxCurProject != nullptr) { wellList = zxCurProject->getChildren(iDataModelType::sTypeWell); } // 清理数据中心的原来的数据 for(int i = 0; i < wellList.size(); i++) { ZxDataWell* pWellObj = dynamic_cast(wellList[i]); // 跳过当前井 if(!pWellObj || pWellObj->getName() == sCurrentWell) { continue; } // 判断当前是否已经将该数据添加到数据中心了 nmDataWellBase* pWell = nmDataAnalyzeManager::getCurrentInstance()->findWellByName(pWellObj->getName()); if(pWell != nullptr) { // 存在,则从数据中心先删除(图元和井数据) nmDataAnalyzeManager::getCurrentInstance()->removeWellDataAndPlot(pWell); pWell = nullptr; } } // 根据用户选择,将井数据添加到数据中心 foreach(const WellDataRow& well, vecSelectedWells) { if(well.bIsIncluded) { // 如果井被选中包含 for(int i = 0; i < wellList.size(); i++) { ZxDataWell* pWellObj = dynamic_cast(wellList[i]); // 跳过当前井 if(!pWellObj || pWellObj->getName() == sCurrentWell) { continue; } if(pWellObj->getName() == well.sName) { // 找到对应的井对象 nmDataAnalyzeManager::getCurrentInstance()->appendWellData(pWellObj); // 添加到数据中心 nmDataWellBase* pWell = nmDataAnalyzeManager::getCurrentInstance()->findWellByName(pWellObj->getName()); // TODO: 计算井的历史双对数/半对数数据 QVector> vvecHistoryPressureData; QVector> vvecHistoryLogData; QVector> vvecHistorySemiLogData; nmDataAnalyzeManager::getCurrentInstance()->calculationLogData(pWell, vvecHistoryPressureData, vvecHistoryLogData, vvecHistorySemiLogData); // 存储历史数据到井对象 pWell->setHistoryPressure(vvecHistoryPressureData); pWell->setHistoryLogLog(vvecHistoryLogData); pWell->setHistorySemiLog(vvecHistorySemiLogData); break; } } } } // 更新地图上的井图元 //emit sigUpdateWellPlot(nmDataAnalyzeManager::getCurrentInstance()); nmDataAnalyzeManager::getCurrentInstance()->updateWellPlotByDataManager(); // 刷新下侧参数栏 //emit sigIncludeWells(); nmWxParameterProperty::notifyUpdateTable(); fillResultWellCombo(sCurrentWell); } } //void nmWxNumericalDesign::onIgnoreCheckToggled(bool checked) //{ // // 如果 checked 为 true (复选框被勾选),我们希望禁用 m_pDtMaxLineEdit。 // // 所以调用 setEnabled(false)。 // // 如果 checked 为 false (复选框未勾选),我们希望启用 m_pDtMaxLineEdit。 // // 所以调用 setEnabled(true)。 // m_pDtMaxLineEdit->setEnabled(!checked); //} void nmWxNumericalDesign::onOutputResultFieldsToggled(bool checked) { // 根据主复选框的状态启用或禁用相关组件 m_pOutputAutomaticRadio->setEnabled(checked); // m_pOutputManualRadio->setEnabled(checked); // // 特别处理 m_pOutputManualIconButton: // 它只有在 m_pOutputResultFieldsCheck 勾选 且 m_pOutputManualRadio 选中时才启用 if(checked && m_pOutputManualRadio->isChecked()) { // m_pOutputManualIconButton->setEnabled(true); // } else { m_pOutputManualIconButton->setEnabled(false); // } } //void nmWxNumericalDesign::onTimeReferenceSystemToggled(bool checked) //{ // // 只有当按钮被选中时才执行 // if(!checked) { // return; // } // // nmDataTimeStepSetting* pTimeStepSetting = nmDataAnalyzeManager::getCurrentInstance()->getTimeStep(); // // if(!pTimeStepSetting) { // return; // } // // // 判断是哪个单选按钮触发的 // if(m_pAbsoluteRadio->isChecked()) { // pTimeStepSetting->setTimeReferenceSystem(TimeReferenceSystem::Absolute); // } else if(m_pElapsedRadio->isChecked()) { // pTimeStepSetting->setTimeReferenceSystem(TimeReferenceSystem::Elapsed); // } // // // 接下来,用数据模型中转换后的新值刷新UI // updateUiFromData(); //} void nmWxNumericalDesign::updateUiFromData() { nmDataTimeStepSetting* pTimeStepSetting = nmDataAnalyzeManager::getCurrentInstance()->getTimeStep(); if(!pTimeStepSetting) { return; } // 使用组件的更新方法 if(m_pTimeGrowthExponentCom) { m_pTimeGrowthExponentCom->updateValueFromOrigin(); } if(m_pDtMinCom) { m_pDtMinCom->updateValueFromOrigin(); } if(m_pDtMaxCom) { m_pDtMaxCom->updateValueFromOrigin(); } //// 阻塞信号 //m_pTimeGrowthExponentLineEdit->blockSignals(true); //m_pDtMinLineEdit->blockSignals(true); //m_pDtMaxLineEdit->blockSignals(true); //// 更新UI值 //m_pTimeGrowthExponentLineEdit->setText(QString::number(pTimeStepSetting->getTimeGrowthExponent().getValue().toDouble())); //m_pDtMinLineEdit->setText(QString::number(pTimeStepSetting->getMinDeltaTAttribute().getValue().toDouble())); //m_pDtMaxLineEdit->setText(QString::number(pTimeStepSetting->getMaxDeltaTAttribute().getValue().toDouble())); //// 恢复信号 //m_pTimeGrowthExponentLineEdit->blockSignals(false); //m_pDtMinLineEdit->blockSignals(false); //m_pDtMaxLineEdit->blockSignals(false); } //void nmWxNumericalDesign::updateUiFromData() //{ // nmDataTimeStepSetting* pTimeStepSetting = nmDataAnalyzeManager::getCurrentInstance()->getTimeStep(); // // if(!pTimeStepSetting) { // return; // } // // // 阻塞组件发出信号 // //m_pFromAbsoluteDateTimeEdit->blockSignals(true); // //m_pFromElapsedLineEdit->blockSignals(true); // //m_pSimulateUntilAbsoluteDateTimeEdit->blockSignals(true); // //m_pSimulateUntilElapsedLineEdit->blockSignals(true); // m_pTimeGrowthExponentLineEdit->blockSignals(true); // m_pUseCoarseSteppingCheck->blockSignals(true); // m_pDtMinLineEdit->blockSignals(true); // m_pDtMaxLineEdit->blockSignals(true); // m_pIgnoreCheck->blockSignals(true); // // // 更新时间参照系单选按钮 // if(pTimeStepSetting->getTimeReferenceSystem() == TimeReferenceSystem::Absolute) { // m_pAbsoluteRadio->setChecked(true); // } else { // m_pElapsedRadio->setChecked(true); // } // // // 根据数据模型的参照系来决定填充哪个UI组件 // //bool isAbsolute = (pTimeStepSetting->getTimeReferenceSystem() == TimeReferenceSystem::Absolute); // // // 设置需要显示那个组件 // //m_pFromStackedLayout->setCurrentIndex(isAbsolute ? 1 : 0); // //m_pSimulateUntilStackedLayout->setCurrentIndex(isAbsolute ? 1 : 0); // // // 统一处理可见性和数据填充 // //if(isAbsolute) { // // // 绝对时间 // // QDateTime fromTime = pTimeStepSetting->getFromTimeAttribute().getValue().toDateTime(); // // m_pFromAbsoluteDateTimeEdit->setDateTime(fromTime); // // // QDateTime untilTime = pTimeStepSetting->getToTimeAttribute().getValue().toDateTime(); // // m_pSimulateUntilAbsoluteDateTimeEdit->setDateTime(untilTime); // //} else { // // // 流逝时间 // // double dFromTime = pTimeStepSetting->getFromTimeAttribute().getValue().toDouble(); // // m_pFromElapsedLineEdit->setText(QString::number(dFromTime)); // // // double toTime = pTimeStepSetting->getToTimeAttribute().getValue().toDouble(); // // m_pSimulateUntilElapsedLineEdit->setText(QString::number(toTime)); // //} // // // 更新其他时间步进组件 // //m_pTimeGrowthExponentLineEdit->setText(QString::number(pTimeStepSetting->getTimeGrowthExponent())); // m_pTimeGrowthExponentLineEdit->setText("1.0"); // m_pUseCoarseSteppingCheck->setChecked(pTimeStepSetting->getUseCoarseStepping()); // m_pDtMinLineEdit->setText(pTimeStepSetting->getMinDeltaTAttribute().getValue().toString()); // m_pDtMaxLineEdit->setText(pTimeStepSetting->getMaxDeltaTAttribute().getValue().toString()); // m_pIgnoreCheck->setChecked(pTimeStepSetting->getIgnoreMaxDeltaT()); // // // 获取步长单位 // QString currentUnit = pTimeStepSetting->getMinDeltaTAttribute().getUnit(); // // if(m_pTimeUnitComboBox->count() == 0) { // QStringList listUnits = pTimeStepSetting->getMinDeltaTAttribute().getListUnitSelections(); // m_pTimeUnitComboBox->addItems(listUnits); // } // // int index = m_pTimeUnitComboBox->findText(currentUnit); // // if(index != -1) { // m_pTimeUnitComboBox->setCurrentIndex(index); // } // // // 恢复 // //m_pFromAbsoluteDateTimeEdit->blockSignals(false); // //m_pFromElapsedLineEdit->blockSignals(false); // //m_pSimulateUntilAbsoluteDateTimeEdit->blockSignals(false); // //m_pSimulateUntilElapsedLineEdit->blockSignals(false); // m_pTimeGrowthExponentLineEdit->blockSignals(false); // m_pUseCoarseSteppingCheck->blockSignals(false); // m_pDtMinLineEdit->blockSignals(false); // m_pDtMaxLineEdit->blockSignals(false); // m_pIgnoreCheck->blockSignals(false); //} //void nmWxNumericalDesign::updateDataFromUi() //{ // nmDataTimeStepSetting* pTimeStepSetting = nmDataAnalyzeManager::getCurrentInstance()->getTimeStep(); // // if(!pTimeStepSetting) { // return; // } // // // 更新时间值 // //if(m_pAbsoluteRadio->isChecked()) { // // pTimeStepSetting->getFromTimeAttribute().setValue(m_pFromAbsoluteDateTimeEdit->dateTime()); // // pTimeStepSetting->getToTimeAttribute().setValue(m_pSimulateUntilAbsoluteDateTimeEdit->dateTime()); // //} else { // // pTimeStepSetting->getFromTimeAttribute().setValue(m_pFromElapsedLineEdit->text().toDouble()); // // pTimeStepSetting->getToTimeAttribute().setValue(m_pSimulateUntilElapsedLineEdit->text().toDouble()); // //} // // // 更新其他时间步进组件 // //pTimeStepSetting->setTimeGrowthExponent(m_pTimeGrowthExponentLineEdit->text().toDouble()); // pTimeStepSetting->setUseCoarseStepping(m_pUseCoarseSteppingCheck->isChecked()); // pTimeStepSetting->getMinDeltaTAttribute().setValue(m_pDtMinLineEdit->text().toDouble()); // pTimeStepSetting->getMaxDeltaTAttribute().setValue(m_pDtMaxLineEdit->text().toDouble()); // pTimeStepSetting->setIgnoreMaxDeltaT(m_pIgnoreCheck->isChecked()); // // // 更新单位 // //QString currentUnit = m_pTimeUnitComboBox->currentText(); // //pTimeStepSetting->getMinDeltaTAttribute().setUnit(currentUnit); // //pTimeStepSetting->getMaxDeltaTAttribute().setUnit(currentUnit); //} void nmWxNumericalDesign::updateDataFromUi() { nmDataTimeStepSetting* pTimeStepSetting = nmDataAnalyzeManager::getCurrentInstance()->getTimeStep(); if(!pTimeStepSetting) { return; } // 使用组件的更新方法 if(m_pTimeGrowthExponentCom) { m_pTimeGrowthExponentCom->updateValueToOrigin(); } if(m_pDtMinCom) { m_pDtMinCom->updateValueToOrigin(); } if(m_pDtMaxCom) { m_pDtMaxCom->updateValueToOrigin(); } //// 更新数据模型 //pTimeStepSetting->getTimeGrowthExponent().setValue(m_pTimeGrowthExponentLineEdit->text().toDouble()); //pTimeStepSetting->getMinDeltaTAttribute().setValue(m_pDtMinLineEdit->text().toDouble()); //pTimeStepSetting->getMaxDeltaTAttribute().setValue(m_pDtMaxLineEdit->text().toDouble()); } // 新增的槽函数:用于在任何组件值改变时,同步数据模型 //void nmWxNumericalDesign::onTimeSteppingUiChanged() //{ // updateDataFromUi(); //} //void nmWxNumericalDesign::onTimeUnitChanged(const QString& newUnit) //{ // nmDataTimeStepSetting* pSetting = nmDataAnalyzeManager::getCurrentInstance()->getTimeStep(); // // if(!pSetting) return; // // QString oldUnit = pSetting->getMinDeltaTAttribute().getUnit(); // // // 仅在 Elapsed 模式下才转换 FromTime / ToTime // if(pSetting->getTimeReferenceSystem() == TimeReferenceSystem::Elapsed) { // // 转换 FromTime // double oldFrom = pSetting->getFromTimeAttribute().getValue().toDouble(); // double newFrom = nmDataAttribute::convertTimeUnit(oldFrom, oldUnit, newUnit); // pSetting->getFromTimeAttribute().setValue(newFrom); // pSetting->getFromTimeAttribute().setUnit(newUnit); // // // 转换 ToTime // double oldTo = pSetting->getToTimeAttribute().getValue().toDouble(); // double newTo = nmDataAttribute::convertTimeUnit(oldTo, oldUnit, newUnit); // pSetting->getToTimeAttribute().setValue(newTo); // pSetting->getToTimeAttribute().setUnit(newUnit); // } else { // // 仅切换单位 // pSetting->getFromTimeAttribute().setUnit(newUnit); // pSetting->getToTimeAttribute().setUnit(newUnit); // } // // // 转换并更新 MinDeltaT // double oldMin = pSetting->getMinDeltaTAttribute().getValue().toDouble(); // double newMin = nmDataAttribute::convertTimeUnit(oldMin, oldUnit, newUnit); // pSetting->getMinDeltaTAttribute().setValue(newMin); // pSetting->getMinDeltaTAttribute().setUnit(newUnit); // // // 转换并更新 MaxDeltaT // if(!pSetting->getIgnoreMaxDeltaT()) { // double oldMax = pSetting->getMaxDeltaTAttribute().getValue().toDouble(); // double newMax = nmDataAttribute::convertTimeUnit(oldMax, oldUnit, newUnit); // pSetting->getMaxDeltaTAttribute().setValue(newMax); // pSetting->getMaxDeltaTAttribute().setUnit(newUnit); // } // // // 刷新 UI // updateUiFromData(); //} //void nmWxNumericalDesign::onResetTimeStep() //{ // nmDataTimeStepSetting* pSetting = nmDataAnalyzeManager::getCurrentInstance()->getTimeStep(); // // if(!pSetting) return; // // // 获取当前井的流量时间数据 // // 获取当前井下流量的时间范围 // QVector vecFlowPoints = nmDataAnalyzeManager::getCurrentInstance()->getCurWellData()->getFlowPoints(); // // // 计算起始时间和终止时间 // // 检查坐标数组是否为空,以防止访问越界 // if(!vecFlowPoints.isEmpty()) { // // 起始时间就是第一个点的横坐标 // double dStartTime = vecFlowPoints.first().x(); // // // 终止时间是所有点的横坐标之和 // double dEndTime = 0.0; // // foreach(const QPointF& point, vecFlowPoints) { // dEndTime += point.x(); // } // // pSetting->resetTimeStep(dStartTime, dEndTime); // } // // // 刷新 UI // updateUiFromData(); //} void nmWxNumericalDesign::onAutomaticFittingClicked() { nmWxAutomaticFitting* dlg = new nmWxAutomaticFitting; dlg->show(); } void nmWxNumericalDesign::onForecastClicked() { nmWxForecast* dlg = new nmWxForecast(); dlg->show(); } void nmWxNumericalDesign::onSensitiveClicked() { nmWxSensitive* dlg = new nmWxSensitive(); dlg->show(); } // 实现通知方法 void nmWxNumericalDesign::notifyTimeDependentSkinChanged(const QString& wellName, bool checked) { // 检查当前是否有活动实例 if(!s_pCurrentInstance) { return; } // 获取当前井数据 nmDataWellBase* pCurrentWell = nmDataAnalyzeManager::getCurrentInstance()->getCurWellData(); if(!pCurrentWell) { return; } // 检查是否是同一口井 if(pCurrentWell->getWellName() == wellName) { // 阻塞信号,避免循环触发 s_pCurrentInstance->m_pTimeDependentCheck->blockSignals(true); // 更新复选框状态 s_pCurrentInstance->m_pTimeDependentCheck->setChecked(checked); // 恢复信号 s_pCurrentInstance->m_pTimeDependentCheck->blockSignals(false); // 同时更新图标按钮的启用状态 s_pCurrentInstance->m_pTimeDependentIconButton->setEnabled(checked); } }