You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
nmWTAI-Platform/Src/nmNum/nmSubWxs/nmWxNumericalDesign.cpp

1124 lines
49 KiB
C++

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include "nmWxNumericalDesign.h"
#include <QScrollArea>
#include <QCoreApplication>
#include <QGroupBox>
#include <QCheckBox>
#include <QComboBox>
#include <QRadioButton>
#include <QLineEdit>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QPushButton>
#include <QLabel>
#include <QMessageBox>
#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_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(); // 初始化主选项组
initOutputGroup(); // 初始化输出组 (新)
initAdvancedGroup(); // 初始化高级组 (新)
initTimeSteppingGroup(); // 初始化时间步进组
initNumericalSettingsGroup(); // 初始化数值设置组 (新)
initButton(); // 初始化生成按钮
// 将各个组添加到滚动区域的布局中
pScrollLayout->addWidget(m_pMainOptionsGroup);
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::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_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::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<WellDataRow> 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<ZxDataWell*>(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<ZxDataWell*>(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<QVector<double>> vvecHistoryPressureData;
QVector<QVector<double>> vvecHistoryLogData;
QVector<QVector<double>> 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();
}
}
//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<QPointF> 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);
}
}