|
|
|
|
|
#include "nmWxEditWellPlot.h"
|
|
|
|
|
|
#include "nmWxNumericalDesign.h"
|
|
|
|
|
|
#include "nmWxParameterProperty.h"
|
|
|
|
|
|
|
|
|
|
|
|
// 包含所有需要的Qt布局和控件头文件
|
|
|
|
|
|
#include <QHBoxLayout>
|
|
|
|
|
|
#include <QVBoxLayout>
|
|
|
|
|
|
#include <QGridLayout>
|
|
|
|
|
|
#include <QLabel>
|
|
|
|
|
|
#include <QLineEdit>
|
|
|
|
|
|
#include <QDebug>
|
|
|
|
|
|
#include <QSplitter>
|
|
|
|
|
|
#include <QCheckBox>
|
|
|
|
|
|
#include <QComboBox>
|
|
|
|
|
|
#include <QPushButton>
|
|
|
|
|
|
#include <QKeyEvent>
|
|
|
|
|
|
|
|
|
|
|
|
#include "iWxWellNew.h"
|
|
|
|
|
|
#include "ZxDataWell.h"
|
|
|
|
|
|
#include "zxSysUtils.h"
|
|
|
|
|
|
|
|
|
|
|
|
#include "nmDataWellBase.h"
|
|
|
|
|
|
#include "nmDataVerticalWell.h"
|
|
|
|
|
|
#include "nmDataVerticalFracturedWell.h"
|
|
|
|
|
|
#include "nmDataHorizontalFracturedWell.h"
|
|
|
|
|
|
|
|
|
|
|
|
#include "nmWxWellboreTrajectoryDisplay.h"
|
|
|
|
|
|
#include "nmWxTimeDependentSkin.h"
|
|
|
|
|
|
|
|
|
|
|
|
#include "nmGUIComponentBase.h" // 基础组件类
|
|
|
|
|
|
#include "nmGUIComponentLineEdit.h" // 用于QLineEdit类型的参数
|
|
|
|
|
|
#include "nmGUIComponentComboBox.h" // 用于QComboBox类型的参数
|
|
|
|
|
|
|
|
|
|
|
|
#include "nmWellEditorController.h"
|
|
|
|
|
|
|
|
|
|
|
|
nmWxEditWellPlot::nmWxEditWellPlot(QWidget *parent, ZxDataWell* pZxDataWell, nmDataWellBase* pNmDataWell)
|
|
|
|
|
|
: iDlgBase(parent)
|
|
|
|
|
|
, m_pMainSplitter(nullptr)
|
|
|
|
|
|
, m_pTopVLayout(nullptr)
|
|
|
|
|
|
, m_pLeftVLayout(nullptr)
|
|
|
|
|
|
, m_pWellNameLineEdit(nullptr)
|
|
|
|
|
|
, m_pWellTypeComboBox(nullptr)
|
|
|
|
|
|
, m_pWellNewWidget(nullptr)
|
|
|
|
|
|
, m_pBottomLeftPanel(nullptr)
|
|
|
|
|
|
, m_pRightPanel(nullptr)
|
|
|
|
|
|
, m_pOverallBottomPanel(nullptr)
|
|
|
|
|
|
, m_pZxDataWell(pZxDataWell)
|
|
|
|
|
|
, m_pNmDataWell(nullptr)
|
|
|
|
|
|
, m_pWellEditorController(nullptr)
|
|
|
|
|
|
, m_bOriginalTimeDependentSkin(false)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 设置新的数据,并创建其深拷贝
|
|
|
|
|
|
if(pNmDataWell) {
|
|
|
|
|
|
// 保存原始状态
|
|
|
|
|
|
m_bOriginalTimeDependentSkin = pNmDataWell->isTimeDependentSkin();
|
|
|
|
|
|
// 返回深拷贝对象。
|
|
|
|
|
|
m_pNmDataWell = pNmDataWell->clone();
|
|
|
|
|
|
// 数据模型变化时,刷新左侧参数面板
|
|
|
|
|
|
connect(m_pNmDataWell, SIGNAL(sigParameterChanged()),
|
|
|
|
|
|
this, SLOT(onWellDataChanged()));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 初始化图标路径
|
|
|
|
|
|
m_sIconDir = QCoreApplication::applicationDirPath();
|
|
|
|
|
|
m_sIconDir = m_sIconDir.section('/', 0, -2); // 获取上一级目录
|
|
|
|
|
|
m_sIconDir += "/Res/Icon/";
|
|
|
|
|
|
|
|
|
|
|
|
this->resize(1121, 633);
|
|
|
|
|
|
// 调用初始化UI的方法
|
|
|
|
|
|
this->initUI();
|
|
|
|
|
|
|
|
|
|
|
|
// 创建控制器
|
|
|
|
|
|
if(m_pNmDataWell && m_pRightPanel) {
|
|
|
|
|
|
m_pWellEditorController = new nmWellEditorController(m_pNmDataWell, m_pRightPanel, this); // 将当前对话框作为父对象
|
|
|
|
|
|
setupControllerConnections(); // 调用连接设置函数
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
nmWxEditWellPlot::~nmWxEditWellPlot()
|
|
|
|
|
|
{
|
|
|
|
|
|
// 在析构函数中清理所有动态创建的组件,避免内存泄漏
|
|
|
|
|
|
qDeleteAll(m_listParameterComponents);
|
|
|
|
|
|
m_listParameterComponents.clear(); // 清空列表
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void nmWxEditWellPlot::initUI()
|
|
|
|
|
|
{
|
|
|
|
|
|
this->initMainLayout();
|
|
|
|
|
|
|
|
|
|
|
|
// 在所有UI元素创建完成后,根据井类型初始化底部左侧面板
|
|
|
|
|
|
// 注意:m_pBottomLeftGridLayout 必须在这里之前被 createLeftPanel() 创建
|
|
|
|
|
|
updateBottomLeftPanelUI();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void nmWxEditWellPlot::initMainLayout()
|
|
|
|
|
|
{
|
|
|
|
|
|
// 创建左侧和右侧面板
|
|
|
|
|
|
QWidget* pLeftContainer = createLeftPanel();
|
|
|
|
|
|
QWidget* pRightPanelWidget = createRightPanel();
|
|
|
|
|
|
|
|
|
|
|
|
// 创建主分割器并添加左右面板
|
|
|
|
|
|
m_pMainSplitter = new QSplitter(Qt::Horizontal, this);
|
|
|
|
|
|
m_pMainSplitter->addWidget(pLeftContainer);
|
|
|
|
|
|
m_pMainSplitter->addWidget(pRightPanelWidget);
|
|
|
|
|
|
|
|
|
|
|
|
// 设置分割器的初始大小比例
|
|
|
|
|
|
QList<int> sizes;
|
|
|
|
|
|
sizes << 373 << 748;
|
|
|
|
|
|
m_pMainSplitter->setSizes(sizes);
|
|
|
|
|
|
|
|
|
|
|
|
// 创建底部面板
|
|
|
|
|
|
QWidget* pBottomPanel = createBottomPanel();
|
|
|
|
|
|
|
|
|
|
|
|
// 创建顶层垂直布局并添加分割器和底部面板
|
|
|
|
|
|
m_pTopVLayout = new QVBoxLayout(this);
|
|
|
|
|
|
m_pTopVLayout->setContentsMargins(0, 0, 0, 0);
|
|
|
|
|
|
m_pTopVLayout->setSpacing(0);
|
|
|
|
|
|
|
|
|
|
|
|
m_pTopVLayout->addWidget(m_pMainSplitter, 1); // 分割器可拉伸
|
|
|
|
|
|
m_pTopVLayout->addWidget(pBottomPanel, 0); // 底部面板固定高度,不拉伸
|
|
|
|
|
|
|
|
|
|
|
|
this->setLayout(m_pTopVLayout); // 将此布局设置为对话框的主布局
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
QWidget* nmWxEditWellPlot::createLeftPanel()
|
|
|
|
|
|
{
|
|
|
|
|
|
//m_pLeftVLayout = new QVBoxLayout();
|
|
|
|
|
|
//m_pLeftVLayout->setContentsMargins(0, 0, 0, 0);
|
|
|
|
|
|
//m_pLeftVLayout->setSpacing(5);
|
|
|
|
|
|
|
|
|
|
|
|
//// 井视图部分 (iWxWellNew) 保持不变
|
|
|
|
|
|
//m_pWellNewWidget = new iWxWellNew(this);
|
|
|
|
|
|
//m_pWellNewWidget->setDataWell(m_pZxDataWell);
|
|
|
|
|
|
//m_pWellNewWidget->setActionMode(DAM_Edit);
|
|
|
|
|
|
//m_pWellNewWidget->initUI();
|
|
|
|
|
|
//m_pWellNewWidget->setWindowFlags(Qt::Widget);
|
|
|
|
|
|
|
|
|
|
|
|
//m_pLeftVLayout->addWidget(m_pWellNewWidget, 1);
|
|
|
|
|
|
|
|
|
|
|
|
//// 1. 创建 m_pBottomLeftPanel (作为 QScrollArea 的容器)
|
|
|
|
|
|
//m_pBottomLeftPanel = new QWidget(this); // 确保它有父对象
|
|
|
|
|
|
//m_pBottomLeftPanel->setStyleSheet("background-color: white;");
|
|
|
|
|
|
|
|
|
|
|
|
//// 2. 在 m_pBottomLeftPanel 内部创建一个垂直布局来容纳 QScrollArea
|
|
|
|
|
|
//QVBoxLayout* pBottomLeftPanelVLayout = new QVBoxLayout(m_pBottomLeftPanel);
|
|
|
|
|
|
//pBottomLeftPanelVLayout->setContentsMargins(0, 0, 0, 0); // 内部布局边距
|
|
|
|
|
|
//pBottomLeftPanelVLayout->setSpacing(0); // 内部布局间距
|
|
|
|
|
|
|
|
|
|
|
|
//// 3. 创建 QScrollArea 并设置其父对象为 m_pBottomLeftPanel
|
|
|
|
|
|
//QScrollArea* pScrollArea = new QScrollArea(m_pBottomLeftPanel);
|
|
|
|
|
|
//pScrollArea->setWidgetResizable(true); // 允许滚动区域调整其内部控件的大小
|
|
|
|
|
|
|
|
|
|
|
|
//// 4. 创建一个 QWidget 作为滚动区域的内容容器
|
|
|
|
|
|
//QWidget* pScrollContent = new QWidget(pScrollArea); // 父对象是 pScrollArea
|
|
|
|
|
|
|
|
|
|
|
|
//// 5. 将 m_pBottomLeftGridLayout 设置为 pScrollContent 的布局
|
|
|
|
|
|
//m_pBottomLeftGridLayout = new QGridLayout(pScrollContent);
|
|
|
|
|
|
//m_pBottomLeftGridLayout->setContentsMargins(10, 10, 10, 10); // 网格布局的边距
|
|
|
|
|
|
//m_pBottomLeftGridLayout->setSpacing(8);
|
|
|
|
|
|
//m_pBottomLeftGridLayout->setColumnStretch(0, 1); // 标签列
|
|
|
|
|
|
//m_pBottomLeftGridLayout->setColumnStretch(1, 2); // 值输入列
|
|
|
|
|
|
|
|
|
|
|
|
//// 6. 将 pScrollContent 设置为滚动区域的内容控件
|
|
|
|
|
|
//pScrollArea->setWidget(pScrollContent);
|
|
|
|
|
|
|
|
|
|
|
|
//// 7. 将滚动区域添加到 m_pBottomLeftPanel 的内部布局中
|
|
|
|
|
|
//pBottomLeftPanelVLayout->addWidget(pScrollArea);
|
|
|
|
|
|
|
|
|
|
|
|
//// 将 m_pBottomLeftPanel (现在包含了滚动区域) 添加到左侧主垂直布局
|
|
|
|
|
|
//m_pLeftVLayout->addWidget(m_pBottomLeftPanel, 1); // 占据垂直布局的1份空间
|
|
|
|
|
|
|
|
|
|
|
|
//// 创建一个 QWidget 来承载左侧的垂直布局
|
|
|
|
|
|
//QWidget* pLeftContainer = new QWidget(this);
|
|
|
|
|
|
//pLeftContainer->setLayout(m_pLeftVLayout);
|
|
|
|
|
|
//pLeftContainer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
|
|
|
|
|
//return pLeftContainer;
|
|
|
|
|
|
|
|
|
|
|
|
m_pLeftVLayout = new QVBoxLayout();
|
|
|
|
|
|
m_pLeftVLayout->setContentsMargins(0, 0, 0, 0);
|
|
|
|
|
|
m_pLeftVLayout->setSpacing(5);
|
|
|
|
|
|
|
|
|
|
|
|
// 1. 创建 m_pBottomLeftPanel (作为 QScrollArea 的容器)
|
|
|
|
|
|
m_pBottomLeftPanel = new QWidget(this); // 确保它有父对象
|
|
|
|
|
|
m_pBottomLeftPanel->setStyleSheet("background-color: white;");
|
|
|
|
|
|
|
|
|
|
|
|
// 2. 在 m_pBottomLeftPanel 内部创建一个垂直布局来容纳 QScrollArea
|
|
|
|
|
|
QVBoxLayout* pBottomLeftPanelVLayout = new QVBoxLayout(m_pBottomLeftPanel);
|
|
|
|
|
|
pBottomLeftPanelVLayout->setContentsMargins(0, 0, 0, 0); // 内部布局边距
|
|
|
|
|
|
pBottomLeftPanelVLayout->setSpacing(0); // 内部布局间距
|
|
|
|
|
|
|
|
|
|
|
|
// 3. 创建 QScrollArea 并设置其父对象为 m_pBottomLeftPanel
|
|
|
|
|
|
QScrollArea* pScrollArea = new QScrollArea(m_pBottomLeftPanel);
|
|
|
|
|
|
pScrollArea->setWidgetResizable(true); // 允许滚动区域调整其内部控件的大小
|
|
|
|
|
|
|
|
|
|
|
|
// 4. 创建一个 QWidget 作为滚动区域的内容容器
|
|
|
|
|
|
QWidget* pScrollContent = new QWidget(pScrollArea); // 父对象是 pScrollArea
|
|
|
|
|
|
|
|
|
|
|
|
// 5. 将 m_pBottomLeftGridLayout 设置为 pScrollContent 的布局
|
|
|
|
|
|
m_pBottomLeftGridLayout = new QGridLayout(pScrollContent);
|
|
|
|
|
|
m_pBottomLeftGridLayout->setContentsMargins(10, 10, 10, 10); // 网格布局的边距
|
|
|
|
|
|
m_pBottomLeftGridLayout->setSpacing(8);
|
|
|
|
|
|
m_pBottomLeftGridLayout->setColumnStretch(0, 1); // 标签列
|
|
|
|
|
|
m_pBottomLeftGridLayout->setColumnStretch(1, 2); // 值输入列
|
|
|
|
|
|
|
|
|
|
|
|
// 6. 将 pScrollContent 设置为滚动区域的内容控件
|
|
|
|
|
|
pScrollArea->setWidget(pScrollContent);
|
|
|
|
|
|
|
|
|
|
|
|
// 7. 将滚动区域添加到 m_pBottomLeftPanel 的内部布局中
|
|
|
|
|
|
pBottomLeftPanelVLayout->addWidget(pScrollArea);
|
|
|
|
|
|
|
|
|
|
|
|
// 将 m_pBottomLeftPanel (现在包含了滚动区域) 添加到左侧主垂直布局
|
|
|
|
|
|
m_pLeftVLayout->addWidget(m_pBottomLeftPanel, 1); // 占据垂直布局的1份空间
|
|
|
|
|
|
|
|
|
|
|
|
// 创建一个 QWidget 来承载左侧的垂直布局
|
|
|
|
|
|
QWidget* pLeftContainer = new QWidget(this);
|
|
|
|
|
|
pLeftContainer->setLayout(m_pLeftVLayout);
|
|
|
|
|
|
pLeftContainer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
|
|
|
|
|
return pLeftContainer;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
QWidget* nmWxEditWellPlot::createRightPanel()
|
|
|
|
|
|
{
|
|
|
|
|
|
m_pRightPanel = new nmWxWellboreTrajectoryDisplay(this);
|
|
|
|
|
|
m_pRightPanel->setContentsMargins(0, 0, 0, 0); // 可以设置外部边距
|
|
|
|
|
|
m_pRightPanel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
|
|
|
|
|
|
|
|
|
|
|
// 设置井数据
|
|
|
|
|
|
m_pRightPanel->setCurrentWellboreData(m_pNmDataWell);
|
|
|
|
|
|
|
|
|
|
|
|
return m_pRightPanel;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
QWidget* nmWxEditWellPlot::createBottomPanel()
|
|
|
|
|
|
{
|
|
|
|
|
|
m_pOverallBottomPanel = new QWidget(this);
|
|
|
|
|
|
m_pOverallBottomPanel->setFixedHeight(80); // 增加高度以容纳两行内容
|
|
|
|
|
|
|
|
|
|
|
|
QVBoxLayout* mainBottomVLayout = new QVBoxLayout(m_pOverallBottomPanel);
|
|
|
|
|
|
mainBottomVLayout->setContentsMargins(5, 5, 5, 5);
|
|
|
|
|
|
mainBottomVLayout->setSpacing(5);
|
|
|
|
|
|
|
|
|
|
|
|
// 第一行:原有的控件
|
|
|
|
|
|
QWidget* hContentContainer = new QWidget(m_pOverallBottomPanel);
|
|
|
|
|
|
QHBoxLayout* bottomContentHLayout = new QHBoxLayout(hContentContainer);
|
|
|
|
|
|
bottomContentHLayout->setContentsMargins(0, 0, 0, 0);
|
|
|
|
|
|
bottomContentHLayout->setSpacing(10);
|
|
|
|
|
|
|
|
|
|
|
|
QCheckBox* myCheckBox = new QCheckBox("Use in multiple well modes", hContentContainer);
|
|
|
|
|
|
QComboBox* myComboBox = new QComboBox(hContentContainer);
|
|
|
|
|
|
myComboBox->addItem("Tested well");
|
|
|
|
|
|
myComboBox->addItem("well_1");
|
|
|
|
|
|
myComboBox->addItem("well_2");
|
|
|
|
|
|
QPushButton* pOKButton = new QPushButton("OK", hContentContainer);
|
|
|
|
|
|
QPushButton* pCancelButton = new QPushButton("Cancel", hContentContainer);
|
|
|
|
|
|
|
|
|
|
|
|
bottomContentHLayout->addWidget(myCheckBox);
|
|
|
|
|
|
bottomContentHLayout->addWidget(myComboBox);
|
|
|
|
|
|
bottomContentHLayout->addStretch();
|
|
|
|
|
|
bottomContentHLayout->addWidget(pOKButton);
|
|
|
|
|
|
bottomContentHLayout->addWidget(pCancelButton);
|
|
|
|
|
|
|
|
|
|
|
|
// 连接按钮到自定义槽函数 (Qt 4 语法)
|
|
|
|
|
|
connect(pOKButton, SIGNAL(clicked()), this, SLOT(onOkClicked()));
|
|
|
|
|
|
connect(pCancelButton, SIGNAL(clicked()), this, SLOT(onCancelClicked()));
|
|
|
|
|
|
|
|
|
|
|
|
// 第二行:时间相关复选框和关联的时钟图标按钮
|
|
|
|
|
|
QWidget* timeContainer = new QWidget(m_pOverallBottomPanel);
|
|
|
|
|
|
QHBoxLayout* pTimeDependentLayout = new QHBoxLayout(timeContainer);
|
|
|
|
|
|
pTimeDependentLayout->setContentsMargins(0, 0, 0, 0);
|
|
|
|
|
|
pTimeDependentLayout->setSpacing(5);
|
|
|
|
|
|
|
|
|
|
|
|
m_pTimeDependentCheck = new QCheckBox(tr("Time dependent"), timeContainer);
|
|
|
|
|
|
m_pTimeDependentCheck->setChecked(m_pNmDataWell->isTimeDependentSkin());
|
|
|
|
|
|
|
|
|
|
|
|
m_pTimeDependentIconButton = new QPushButton(timeContainer);
|
|
|
|
|
|
m_pTimeDependentIconButton->setIcon(QIcon(m_sIconDir + "NmAnalDesign3.png")); // 使用时钟图标
|
|
|
|
|
|
m_pTimeDependentIconButton->setIconSize(QSize(20, 20));
|
|
|
|
|
|
m_pTimeDependentIconButton->setFixedSize(22, 22);
|
|
|
|
|
|
m_pTimeDependentIconButton->setEnabled(m_pNmDataWell->isTimeDependentSkin());
|
|
|
|
|
|
|
|
|
|
|
|
pTimeDependentLayout->addWidget(m_pTimeDependentCheck);
|
|
|
|
|
|
pTimeDependentLayout->addWidget(m_pTimeDependentIconButton);
|
|
|
|
|
|
pTimeDependentLayout->addStretch(); // 添加拉伸器,将它们推到左侧
|
|
|
|
|
|
|
|
|
|
|
|
// 连接复选框状态变化信号到槽函数
|
|
|
|
|
|
connect(m_pTimeDependentCheck, SIGNAL(toggled(bool)),
|
|
|
|
|
|
m_pTimeDependentIconButton, SLOT(setEnabled(bool)));
|
|
|
|
|
|
connect(m_pTimeDependentIconButton, SIGNAL(clicked()),
|
|
|
|
|
|
this, SLOT(onTimeDependentIconClicked()));
|
|
|
|
|
|
|
|
|
|
|
|
connect(m_pTimeDependentCheck, SIGNAL(toggled(bool)),
|
|
|
|
|
|
this, SLOT(onTimeDependentCheckToggled(bool)));
|
|
|
|
|
|
|
|
|
|
|
|
// 将两行内容添加到主垂直布局
|
|
|
|
|
|
mainBottomVLayout->addWidget(hContentContainer);
|
|
|
|
|
|
mainBottomVLayout->addWidget(timeContainer);
|
|
|
|
|
|
|
|
|
|
|
|
return m_pOverallBottomPanel;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void nmWxEditWellPlot::setupControllerConnections()
|
|
|
|
|
|
{
|
|
|
|
|
|
if(!m_pWellEditorController || !m_pRightPanel || !m_pNmDataWell) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// --- 1. nmWxWellboreTrajectoryDisplay (视图) 发出的模式请求信号连接到控制器 ---
|
|
|
|
|
|
// 这些信号会在用户点击工具栏按钮时发出
|
|
|
|
|
|
connect(m_pRightPanel, SIGNAL(requestedEditWellMode(int)),
|
|
|
|
|
|
m_pWellEditorController, SLOT(onRequestEditWellMode(int)));
|
|
|
|
|
|
connect(m_pRightPanel, SIGNAL(requestedEditPerforationsMode(int)),
|
|
|
|
|
|
m_pWellEditorController, SLOT(onRequestEditPerforationsMode(int)));
|
|
|
|
|
|
connect(m_pRightPanel, SIGNAL(requestedNewPerforationMode(int)),
|
|
|
|
|
|
m_pWellEditorController, SLOT(onRequestNewPerforationMode(int)));
|
|
|
|
|
|
connect(m_pRightPanel, SIGNAL(requestedDeletePerforationMode(int)),
|
|
|
|
|
|
m_pWellEditorController, SLOT(onRequestDeletePerforationMode(int)));
|
|
|
|
|
|
connect(m_pRightPanel, SIGNAL(requestedSnapPerforationMode(int)),
|
|
|
|
|
|
m_pWellEditorController, SLOT(onRequestSnapPerforationMode(int)));
|
|
|
|
|
|
connect(m_pRightPanel, SIGNAL(sigClearViewStates()),
|
|
|
|
|
|
m_pWellEditorController, SLOT(slotClearViewStates()));
|
|
|
|
|
|
|
|
|
|
|
|
// --- 2. nmWxWellboreTrajectoryDisplay (视图) 发出的视图切换信号连接到控制器 ---
|
|
|
|
|
|
connect(m_pRightPanel, SIGNAL(currentViewChanged(int)),
|
|
|
|
|
|
m_pWellEditorController, SLOT(onViewChanged(int)));
|
|
|
|
|
|
// 井筒点移动信号到控制器 (只在拖动结束时触发)
|
|
|
|
|
|
connect(m_pRightPanel, SIGNAL(sigWellboreTrajectoryPointMoved(QPointF)),
|
|
|
|
|
|
m_pWellEditorController, SLOT(slotWellboreTrajectoryPointMoved(QPointF)));
|
|
|
|
|
|
// 射孔拖动信号到控制器 (只在拖动结束时触发)
|
|
|
|
|
|
connect(m_pRightPanel, SIGNAL(sigPerforationDragFinished(nmDataPerforation*, double, double)),
|
|
|
|
|
|
m_pWellEditorController, SLOT(slotPerforationDragFinished(nmDataPerforation*, double, double)));
|
|
|
|
|
|
// 射孔添加模式,发送给控制器
|
|
|
|
|
|
connect(m_pRightPanel, SIGNAL(sigTryAddNewPerforation(QPointF, double, double, QLineF)),
|
|
|
|
|
|
m_pWellEditorController, SLOT(slotTryAddNewPerforation(QPointF, double, double, QLineF)));
|
|
|
|
|
|
// 射孔删除模式
|
|
|
|
|
|
connect(m_pRightPanel, SIGNAL(sigTryDeletePerforation(nmDataPerforation*)),
|
|
|
|
|
|
m_pWellEditorController, SLOT(slotDeletePerforation(nmDataPerforation*)));
|
|
|
|
|
|
// 更新裂缝俯视位置
|
|
|
|
|
|
connect(m_pRightPanel, SIGNAL(sigFractureGeometryDragFinished(double, double)),
|
|
|
|
|
|
m_pWellEditorController, SLOT(slotFractureGeometryChanged(double, double)));
|
|
|
|
|
|
// 连接截面图下更新裂缝位置的信号槽
|
|
|
|
|
|
connect(m_pRightPanel, SIGNAL(sigRequestFractureRectUpdate(qreal, qreal)),
|
|
|
|
|
|
m_pWellEditorController, SLOT(slotHandleFractureRectUpdate(qreal, qreal)));
|
|
|
|
|
|
// 射孔更新
|
|
|
|
|
|
connect(m_pRightPanel, SIGNAL(sigFractureDragFinished(const QMap<nmDataPerforation*, QPair<double, double>>&)),
|
|
|
|
|
|
m_pWellEditorController, SLOT(slotUpdatePerforations(const QMap<nmDataPerforation*, QPair<double, double>>&)));
|
|
|
|
|
|
// 裂缝半长更新
|
|
|
|
|
|
connect(m_pRightPanel, SIGNAL(sigFractureHalfLengthChanged(double)),
|
|
|
|
|
|
m_pWellEditorController, SLOT(slotUpdateFractureHalfLength(double)));
|
|
|
|
|
|
// 井身位置更新
|
|
|
|
|
|
connect(m_pRightPanel, SIGNAL(sigWellboreDragFinished(QPointF)),
|
|
|
|
|
|
m_pWellEditorController, SLOT(slotUpdateWellborePos(QPointF)));
|
|
|
|
|
|
// 多段压裂水平井截面图裂缝位置更新
|
|
|
|
|
|
connect(m_pRightPanel, SIGNAL(sigFractureGeometryChanged(double, double)),
|
|
|
|
|
|
m_pWellEditorController, SLOT(slotHFWellFractureGeometryChanged(double, double)));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void nmWxEditWellPlot::updateBottomLeftPanelUI()
|
|
|
|
|
|
{
|
|
|
|
|
|
if(!m_pNmDataWell || !m_pBottomLeftGridLayout) {
|
|
|
|
|
|
qDebug() << "nmDataWellBase pointer or m_pBottomLeftGridLayout is null in updateBottomLeftPanelUI!";
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 1. 清空当前网格布局中的所有控件
|
|
|
|
|
|
// 并从 m_listParameterComponents 中删除并释放所有组件
|
|
|
|
|
|
QLayoutItem *item;
|
|
|
|
|
|
|
|
|
|
|
|
while((item = m_pBottomLeftGridLayout->takeAt(0)) != nullptr) {
|
|
|
|
|
|
if(item->widget()) {
|
|
|
|
|
|
// 从 m_listParameterComponents 中移除并删除对应的组件
|
|
|
|
|
|
nmGUIComponentBase* component = qobject_cast<nmGUIComponentBase*>(item->widget());
|
|
|
|
|
|
|
|
|
|
|
|
if(component) {
|
|
|
|
|
|
m_listParameterComponents.removeOne(component); // 从列表中移除
|
|
|
|
|
|
// component->deleteLater(); // item->widget() 会处理删除
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
item->widget()->deleteLater(); // 删除Qt控件
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
delete item; // 删除布局项
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
m_listParameterComponents.clear(); // 确保列表清空
|
|
|
|
|
|
|
|
|
|
|
|
int currentRow = 0; // 用于跟踪当前添加控件的行数
|
|
|
|
|
|
|
|
|
|
|
|
// 2. 添加井名称的 QLabel 和 QLineEdit
|
|
|
|
|
|
m_pWellNameLineEdit = nullptr;
|
|
|
|
|
|
QLabel* pWellNameLabel = new QLabel(tr("Well Name:"), this);
|
|
|
|
|
|
// 使用成员变量 m_pWellNameLineEdit,确保在槽函数中可以访问
|
|
|
|
|
|
m_pWellNameLineEdit = new QLineEdit(this);
|
|
|
|
|
|
m_pWellNameLineEdit->setText(m_pNmDataWell->getWellName());
|
|
|
|
|
|
|
|
|
|
|
|
// 连接编辑框的编辑完成信号到槽函数
|
|
|
|
|
|
connect(m_pWellNameLineEdit, SIGNAL(editingFinished()),
|
|
|
|
|
|
this, SLOT(onWellNameEditingFinished()));
|
|
|
|
|
|
|
|
|
|
|
|
m_pBottomLeftGridLayout->addWidget(pWellNameLabel, currentRow, 0, 1, 1);
|
|
|
|
|
|
m_pBottomLeftGridLayout->addWidget(m_pWellNameLineEdit, currentRow, 1, 1, 1);
|
|
|
|
|
|
currentRow++; // 行号递增
|
|
|
|
|
|
|
|
|
|
|
|
// 3. 创建并添加 QLabel 和 QComboBox
|
|
|
|
|
|
m_pWellTypeComboBox = nullptr;
|
|
|
|
|
|
QLabel* pWellTypeLabel = new QLabel(tr("Well Type:"), this);
|
|
|
|
|
|
m_pWellTypeComboBox = new QComboBox(this);
|
|
|
|
|
|
m_pWellTypeComboBox->addItem(tr("Vertical Well"), NM_WELL_MODEL::Vertical_Well);
|
|
|
|
|
|
m_pWellTypeComboBox->addItem(tr("Vertical Fractured Well"), NM_WELL_MODEL::Vertical_Fractured_Well);
|
|
|
|
|
|
m_pWellTypeComboBox->addItem(tr("Horizontal Fractured Well"), NM_WELL_MODEL::Horizontal_Fractured_Well);
|
|
|
|
|
|
|
|
|
|
|
|
// 重新连接信号槽
|
|
|
|
|
|
connect(m_pWellTypeComboBox, SIGNAL(currentIndexChanged(int)),
|
|
|
|
|
|
this, SLOT(onWellTypeChanged(int)));
|
|
|
|
|
|
|
|
|
|
|
|
// 4. 根据当前 m_pNmDataWell 的类型设置选中项
|
|
|
|
|
|
NM_WELL_MODEL currentType = m_pNmDataWell->getWellType();
|
|
|
|
|
|
int index = m_pWellTypeComboBox->findData(currentType);
|
|
|
|
|
|
|
|
|
|
|
|
if(index != -1) {
|
|
|
|
|
|
m_pWellTypeComboBox->setCurrentIndex(index);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 5. 将 QLabel 和 QComboBox 添加到布局
|
|
|
|
|
|
m_pBottomLeftGridLayout->addWidget(pWellTypeLabel, currentRow, 0, 1, 1);
|
|
|
|
|
|
m_pBottomLeftGridLayout->addWidget(m_pWellTypeComboBox, currentRow, 1, 1, 1);
|
|
|
|
|
|
currentRow++;
|
|
|
|
|
|
|
|
|
|
|
|
// 6. 根据井类型动态添加参数
|
|
|
|
|
|
// 这里使用 dynamic_cast 来判断具体的井类型并访问其特有属性
|
|
|
|
|
|
|
|
|
|
|
|
// 井的通用参数(所有井类型都可能有的)
|
|
|
|
|
|
// Location---位置
|
|
|
|
|
|
// addLineEditComponentToGrid(m_pNmDataWell->getInputWellHead(), currentRow);
|
|
|
|
|
|
// addLineEditComponentToGrid(m_pNmDataWell->getWellHeadX(), currentRow);
|
|
|
|
|
|
// addLineEditComponentToGrid(m_pNmDataWell->getWellHeadY(), currentRow);
|
|
|
|
|
|
addLineEditComponentToGrid(m_pNmDataWell->getX(), currentRow);
|
|
|
|
|
|
addLineEditComponentToGrid(m_pNmDataWell->getY(), currentRow);
|
|
|
|
|
|
|
|
|
|
|
|
// Geometry and properties---几何与属性
|
|
|
|
|
|
addLineEditComponentToGrid(m_pNmDataWell->getDrillFloorElevation(), currentRow);
|
|
|
|
|
|
addLineEditComponentToGrid(m_pNmDataWell->getRadius(), currentRow);
|
|
|
|
|
|
addLineEditComponentToGrid(m_pNmDataWell->getZw(), currentRow);
|
|
|
|
|
|
addLineEditComponentToGrid(m_pNmDataWell->getWellLength(), currentRow);
|
|
|
|
|
|
// addLineEditComponentToGrid(m_pNmDataWell->getRateDependentSkin(), currentRow);
|
|
|
|
|
|
addLineEditComponentToGrid(m_pNmDataWell->getdSdQ(), currentRow);
|
|
|
|
|
|
|
|
|
|
|
|
// Wellbore---井储
|
|
|
|
|
|
addComboBoxComponentToGrid(m_pNmDataWell->getWellboreModel(), currentRow);
|
|
|
|
|
|
addLineEditComponentToGrid(m_pNmDataWell->getWellboreStorage(), currentRow);
|
|
|
|
|
|
addLineEditComponentToGrid(m_pNmDataWell->getFinalWellboreStorage(), currentRow);
|
|
|
|
|
|
addLineEditComponentToGrid(m_pNmDataWell->getCInitialCFinal(), currentRow);
|
|
|
|
|
|
addLineEditComponentToGrid(m_pNmDataWell->getDtChangingStorage(), currentRow);
|
|
|
|
|
|
addLineEditComponentToGrid(m_pNmDataWell->getLeakSkin(), currentRow);
|
|
|
|
|
|
|
|
|
|
|
|
// Bottomhole conditions---井底条件
|
|
|
|
|
|
addLineEditComponentToGrid(m_pNmDataWell->getBottomholeMD(), currentRow);
|
|
|
|
|
|
|
|
|
|
|
|
// 射孔段的表皮系数(如果井有射孔段)
|
|
|
|
|
|
if(m_pNmDataWell->getPerforationCount() > 0) {
|
|
|
|
|
|
for(int i = 0; i < m_pNmDataWell->getPerforationCount(); ++i) {
|
|
|
|
|
|
nmDataPerforation* perforation = m_pNmDataWell->getPerforation(i);
|
|
|
|
|
|
|
|
|
|
|
|
if(perforation) {
|
|
|
|
|
|
addLineEditComponentToGrid(perforation->getName(), currentRow);
|
|
|
|
|
|
addLineEditComponentToGrid(perforation->getMdStart(), currentRow);
|
|
|
|
|
|
addLineEditComponentToGrid(perforation->getMdEnd(), currentRow);
|
|
|
|
|
|
addLineEditComponentToGrid(perforation->getSkin(), currentRow);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 根据具体的井模型添加特有参数
|
|
|
|
|
|
if(nmDataVerticalFracturedWell * pVFWell = dynamic_cast<nmDataVerticalFracturedWell * >(m_pNmDataWell)) {
|
|
|
|
|
|
// 垂直裂缝井特有参数
|
|
|
|
|
|
addVerticalFracturedWellParameters(pVFWell, currentRow); // 委托给私有辅助函数
|
|
|
|
|
|
} else if(nmDataHorizontalFracturedWell * pHFWell = dynamic_cast<nmDataHorizontalFracturedWell * >(m_pNmDataWell)) {
|
|
|
|
|
|
// 多段压裂水平井特有参数
|
|
|
|
|
|
addHorizontalFracturedWellParameters(pHFWell, currentRow); // 委托给私有辅助函数
|
|
|
|
|
|
} else if(nmDataVerticalWell * pVWell = dynamic_cast<nmDataVerticalWell * >(m_pNmDataWell)) {
|
|
|
|
|
|
// 直井特有参数
|
|
|
|
|
|
addVerticalWellParameters(pVWell, currentRow); // 委托给私有辅助函数
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 强制刷新布局和调整面板大小
|
|
|
|
|
|
// m_pBottomLeftGridLayout->update();
|
|
|
|
|
|
// m_pBottomLeftPanel->adjustSize(); // 调整面板大小以适应新内容
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 辅助函数:向网格布局中添加 nmGUIComponentLineEdit
|
|
|
|
|
|
void nmWxEditWellPlot::addLineEditComponentToGrid(nmDataAttribute& attribute, int& row)
|
|
|
|
|
|
{
|
|
|
|
|
|
// const_cast 是安全的,因为 nmGUIComponentLineEdit 内部会操作 nmDataAttribute 的非 const 引用,
|
|
|
|
|
|
// 而这个引用在 nmDataWell 对象内部是可修改的。
|
|
|
|
|
|
nmGUIComponentLineEdit* component = new nmGUIComponentLineEdit(const_cast<nmDataAttribute*>(&attribute), true, m_pBottomLeftPanel);
|
|
|
|
|
|
// 设置实时更新数据
|
|
|
|
|
|
component->setIsRealTimeUpdateValue(true);
|
|
|
|
|
|
m_listParameterComponents.append(component); // 添加到管理列表中
|
|
|
|
|
|
m_pBottomLeftGridLayout->addWidget(component, row, 0, 1, 2); // 跨两列
|
|
|
|
|
|
row++; // 行号递增
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 辅助函数:向网格布局中添加 nmGUIComponentComboBox
|
|
|
|
|
|
void nmWxEditWellPlot::addComboBoxComponentToGrid(nmDataAttribute& attribute, int& row)
|
|
|
|
|
|
{
|
|
|
|
|
|
nmGUIComponentComboBox* component = new nmGUIComponentComboBox(const_cast<nmDataAttribute*>(&attribute), true, m_pBottomLeftPanel);
|
|
|
|
|
|
m_listParameterComponents.append(component); // 添加到管理列表中
|
|
|
|
|
|
m_pBottomLeftGridLayout->addWidget(component, row, 0, 1, 2); // 跨两列
|
|
|
|
|
|
row++; // 行号递增
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 私有辅助函数:添加垂直井特有参数
|
|
|
|
|
|
void nmWxEditWellPlot::addVerticalWellParameters(nmDataVerticalWell* well, int& row)
|
|
|
|
|
|
{
|
|
|
|
|
|
if(!well) return;
|
|
|
|
|
|
|
|
|
|
|
|
// 添加垂直井特有的参数
|
|
|
|
|
|
addLineEditComponentToGrid(well->getPerforationLength(), row);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 私有辅助函数:添加垂直压裂井特有参数
|
|
|
|
|
|
void nmWxEditWellPlot::addVerticalFracturedWellParameters(nmDataVerticalFracturedWell* well, int& row)
|
|
|
|
|
|
{
|
|
|
|
|
|
if(!well) return;
|
|
|
|
|
|
|
|
|
|
|
|
// 添加垂直压裂井特有的参数
|
|
|
|
|
|
addComboBoxComponentToGrid(well->getFractureModel(), row);
|
|
|
|
|
|
addLineEditComponentToGrid(well->getFractureHalfLength(), row);
|
|
|
|
|
|
addLineEditComponentToGrid(well->getFractureHeight(), row);
|
|
|
|
|
|
addLineEditComponentToGrid(well->getFractureMidPointHeight(), row);
|
|
|
|
|
|
addLineEditComponentToGrid(well->getWidth(), row);
|
|
|
|
|
|
addLineEditComponentToGrid(well->getFractureAngle(), row);
|
|
|
|
|
|
addLineEditComponentToGrid(well->getDfc(), row);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 私有辅助函数:添加水平压裂井特有参数
|
|
|
|
|
|
void nmWxEditWellPlot::addHorizontalFracturedWellParameters(nmDataHorizontalFracturedWell* well, int& row)
|
|
|
|
|
|
{
|
|
|
|
|
|
if(!well) return;
|
|
|
|
|
|
|
|
|
|
|
|
// 添加水平压裂井特有的参数
|
|
|
|
|
|
addLineEditComponentToGrid(well->getDrainAngle(), row);
|
|
|
|
|
|
addComboBoxComponentToGrid(well->getModelingType(), row);
|
|
|
|
|
|
addComboBoxComponentToGrid(well->getFractureModel(), row);
|
|
|
|
|
|
addLineEditComponentToGrid(well->getNumberOfFractures(), row);
|
|
|
|
|
|
addLineEditComponentToGrid(well->getFractureHalfLength(), row);
|
|
|
|
|
|
addLineEditComponentToGrid(well->getFractureHeight(), row);
|
|
|
|
|
|
addLineEditComponentToGrid(well->getFractureMidPointHeight(), row);
|
|
|
|
|
|
addLineEditComponentToGrid(well->getWidth(), row);
|
|
|
|
|
|
addLineEditComponentToGrid(well->getFractureAngle(), row);
|
|
|
|
|
|
addLineEditComponentToGrid(well->getStimulatedZonesAroundFracture(), row);
|
|
|
|
|
|
addLineEditComponentToGrid(well->getStimulationRadius(), row);
|
|
|
|
|
|
addLineEditComponentToGrid(well->getPermeabilityMultiplier(), row);
|
|
|
|
|
|
addLineEditComponentToGrid(well->getPorosityMultiplier(), row);
|
|
|
|
|
|
addLineEditComponentToGrid(well->getDfc(), row);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
nmDataWellBase* nmWxEditWellPlot::getModifiedDataWell()
|
|
|
|
|
|
{
|
|
|
|
|
|
return m_pNmDataWell;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void nmWxEditWellPlot::onOkClicked()
|
|
|
|
|
|
{
|
|
|
|
|
|
if(!m_pNmDataWell) {
|
|
|
|
|
|
qDebug() << "nmDataWellBase pointer is null in onOkClicked!";
|
|
|
|
|
|
iDlgBase::reject();
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 应用时间变表皮状态到真实数据
|
|
|
|
|
|
nmDataWellBase* pRealWell = nmDataAnalyzeManager::getCurrentInstance()->getCurWellData();
|
|
|
|
|
|
|
|
|
|
|
|
if(pRealWell && pRealWell->getWellName() == m_pNmDataWell->getWellName()) {
|
|
|
|
|
|
pRealWell->setTimeDependentSkin(m_pNmDataWell->isTimeDependentSkin());
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
nmDataAnalyzeManager* manager = nmDataAnalyzeManager::getCurrentInstance();
|
|
|
|
|
|
NM_WELL_MODEL currentWellType = m_pNmDataWell->getWellType();
|
|
|
|
|
|
|
|
|
|
|
|
// 根据井类型调用对应的update方法
|
|
|
|
|
|
if(currentWellType == NM_WELL_MODEL::Vertical_Well) {
|
|
|
|
|
|
// 转换为垂直井类型
|
|
|
|
|
|
if(auto * verticalWell = dynamic_cast<nmDataVerticalWell * >(m_pNmDataWell)) {
|
|
|
|
|
|
QVector<nmDataVerticalWell> wells;
|
|
|
|
|
|
wells.append(*verticalWell); // 添加井的副本到QVector中
|
|
|
|
|
|
manager->updateVerticalWells(wells);
|
|
|
|
|
|
}
|
|
|
|
|
|
} else if(currentWellType == NM_WELL_MODEL::Vertical_Fractured_Well) {
|
|
|
|
|
|
// 转换为垂直压裂井类型
|
|
|
|
|
|
if(auto * verticalFracturedWell = dynamic_cast<nmDataVerticalFracturedWell * >(m_pNmDataWell)) {
|
|
|
|
|
|
QVector<nmDataVerticalFracturedWell> wells;
|
|
|
|
|
|
wells.append(*verticalFracturedWell); // 添加井的副本到QVector中
|
|
|
|
|
|
manager->updateVerticalFracturedWells(wells);
|
|
|
|
|
|
}
|
|
|
|
|
|
} else if(currentWellType == NM_WELL_MODEL::Horizontal_Fractured_Well) {
|
|
|
|
|
|
// 转换为水平压裂井类型
|
|
|
|
|
|
if(auto * horizontalFracturedWell = dynamic_cast<nmDataHorizontalFracturedWell * >(m_pNmDataWell)) {
|
|
|
|
|
|
QVector<nmDataHorizontalFracturedWell> wells;
|
|
|
|
|
|
wells.append(*horizontalFracturedWell); // 添加井的副本到QVector中
|
|
|
|
|
|
manager->updateHorizontalFracturedWells(wells);
|
|
|
|
|
|
}
|
|
|
|
|
|
} else {
|
|
|
|
|
|
iDlgBase::reject();
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 更新完成后,通知参数界面刷新
|
|
|
|
|
|
nmWxParameterProperty::notifyUpdateTable();
|
|
|
|
|
|
|
|
|
|
|
|
accept();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void nmWxEditWellPlot::onCancelClicked()
|
|
|
|
|
|
{
|
|
|
|
|
|
if(m_pNmDataWell) {
|
|
|
|
|
|
|
|
|
|
|
|
nmWxNumericalDesign::notifyTimeDependentSkinChanged(m_pNmDataWell->getWellName(), m_bOriginalTimeDependentSkin);
|
|
|
|
|
|
|
|
|
|
|
|
delete m_pNmDataWell;
|
|
|
|
|
|
m_pNmDataWell = nullptr;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
reject();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void nmWxEditWellPlot::onWellDataChanged()
|
|
|
|
|
|
{
|
|
|
|
|
|
// 重新加载所有参数,将模型中的新值显示在UI上
|
|
|
|
|
|
updateBottomLeftPanelUI();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void nmWxEditWellPlot::onWellTypeChanged(int index)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 1. 获取选择的井类型枚举值
|
|
|
|
|
|
// 使用 itemData() 方法获取在 addItem() 时关联的枚举值
|
|
|
|
|
|
QVariant selectedData = m_pWellTypeComboBox->itemData(index);
|
|
|
|
|
|
|
|
|
|
|
|
if(!selectedData.isValid()) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
NM_WELL_MODEL newWellType = static_cast<NM_WELL_MODEL>(selectedData.toInt());
|
|
|
|
|
|
|
|
|
|
|
|
// 2. 获取当前井的类型
|
|
|
|
|
|
NM_WELL_MODEL currentWellType = m_pNmDataWell->getWellType();
|
|
|
|
|
|
|
|
|
|
|
|
// 3. 如果新旧类型相同,则无需操作
|
|
|
|
|
|
if(newWellType == currentWellType) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 4. 实现核心逻辑:创建新对象、复制数据、销毁旧对象
|
|
|
|
|
|
// 保存旧数据模型的指针
|
|
|
|
|
|
nmDataWellBase* pOldWellData = m_pNmDataWell;
|
|
|
|
|
|
|
|
|
|
|
|
// 创建一个新的数据模型对象
|
|
|
|
|
|
nmDataWellBase* pNewWellData = nullptr;
|
|
|
|
|
|
|
|
|
|
|
|
if(newWellType == NM_WELL_MODEL::Vertical_Well) {
|
|
|
|
|
|
pNewWellData = new nmDataVerticalWell();
|
|
|
|
|
|
pNewWellData->setWellType(Vertical_Well);
|
|
|
|
|
|
} else if(newWellType == NM_WELL_MODEL::Vertical_Fractured_Well) {
|
|
|
|
|
|
pNewWellData = new nmDataVerticalFracturedWell();
|
|
|
|
|
|
pNewWellData->setWellType(Vertical_Fractured_Well);
|
|
|
|
|
|
} else if(newWellType == NM_WELL_MODEL::Horizontal_Fractured_Well) {
|
|
|
|
|
|
pNewWellData = new nmDataHorizontalFracturedWell();
|
|
|
|
|
|
pNewWellData->setWellType(Horizontal_Fractured_Well);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 将旧数据中的通用属性复制到新数据中
|
|
|
|
|
|
if(pNewWellData && pOldWellData) {
|
|
|
|
|
|
// 通用几何位置
|
|
|
|
|
|
pNewWellData->setWellName(pOldWellData->getWellName());
|
|
|
|
|
|
pNewWellData->setX(pOldWellData->getX());
|
|
|
|
|
|
pNewWellData->setY(pOldWellData->getY());
|
|
|
|
|
|
pNewWellData->setRadius(pOldWellData->getRadius());
|
|
|
|
|
|
|
|
|
|
|
|
// 历史数据
|
|
|
|
|
|
pNewWellData->setPressurePoints(pOldWellData->getPressurePoints());
|
|
|
|
|
|
pNewWellData->setFlowPoints(pOldWellData->getFlowPoints());
|
|
|
|
|
|
pNewWellData->setIndexF(pOldWellData->getIndexF());
|
|
|
|
|
|
|
|
|
|
|
|
// 结果数据
|
|
|
|
|
|
pNewWellData->setResultPressure(pOldWellData->getResultPressure());
|
|
|
|
|
|
pNewWellData->setResultLogLog(pOldWellData->getResultLogLog());
|
|
|
|
|
|
pNewWellData->setResultSemiLog(pOldWellData->getResultSemiLog());
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 对于裂缝类型的井,需要更新裂缝位置
|
|
|
|
|
|
if(newWellType == NM_WELL_MODEL::Vertical_Fractured_Well) {
|
|
|
|
|
|
if(nmDataVerticalFracturedWell * pVFWell = dynamic_cast<nmDataVerticalFracturedWell * >(pNewWellData)) {
|
|
|
|
|
|
pVFWell->setFracs();
|
|
|
|
|
|
}
|
|
|
|
|
|
} else if(newWellType == NM_WELL_MODEL::Horizontal_Fractured_Well) {
|
|
|
|
|
|
if(nmDataHorizontalFracturedWell * pHFWell = dynamic_cast<nmDataHorizontalFracturedWell * >(pNewWellData)) {
|
|
|
|
|
|
pHFWell->setFracs();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 5. 更新 m_pNmDataWell 指针
|
|
|
|
|
|
m_pNmDataWell = pNewWellData;
|
|
|
|
|
|
|
|
|
|
|
|
// 6. 重新连接信号:先断开旧连接,再连接新对象
|
|
|
|
|
|
if(pOldWellData) {
|
|
|
|
|
|
disconnect(pOldWellData, SIGNAL(sigParameterChanged()), this, SLOT(onWellDataChanged()));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if(m_pNmDataWell) {
|
|
|
|
|
|
connect(m_pNmDataWell, SIGNAL(sigParameterChanged()), this, SLOT(onWellDataChanged()));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 7. 销毁旧控制器并创建新控制器
|
|
|
|
|
|
// 由于控制器是 QObject 的子对象,它会被父对象(this)自动管理内存。
|
|
|
|
|
|
// 但是为了保证逻辑的清晰和安全,我们手动处理。
|
|
|
|
|
|
if(m_pWellEditorController) {
|
|
|
|
|
|
delete m_pWellEditorController;
|
|
|
|
|
|
m_pWellEditorController = nullptr;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if(m_pNmDataWell && m_pRightPanel) {
|
|
|
|
|
|
m_pWellEditorController = new nmWellEditorController(m_pNmDataWell, m_pRightPanel, this);
|
|
|
|
|
|
// 重建控制器后,必须重新连接所有信号
|
|
|
|
|
|
setupControllerConnections();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 8. 销毁旧数据对象
|
|
|
|
|
|
if(pOldWellData) {
|
|
|
|
|
|
delete pOldWellData;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 9. 刷新 UI
|
|
|
|
|
|
updateBottomLeftPanelUI();
|
|
|
|
|
|
|
|
|
|
|
|
// 10. 通知 nmWxWellboreTrajectoryDisplay 视图刷新
|
|
|
|
|
|
if(m_pRightPanel) {
|
|
|
|
|
|
m_pRightPanel->setCurrentWellboreData(m_pNmDataWell); // 重新设置数据
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void nmWxEditWellPlot::onWellNameEditingFinished()
|
|
|
|
|
|
{
|
|
|
|
|
|
if(m_pNmDataWell && m_pWellNameLineEdit) {
|
|
|
|
|
|
// 获取编辑框中的文本并更新数据模型
|
|
|
|
|
|
m_pNmDataWell->setWellName(m_pWellNameLineEdit->text());
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void nmWxEditWellPlot::keyPressEvent(QKeyEvent *event)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 如果按下的键是回车键,则忽略它,不调用父类的 keyPressEvent
|
|
|
|
|
|
if(event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return) {
|
|
|
|
|
|
// 事件已被处理,阻止它继续传播
|
|
|
|
|
|
event->ignore();
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 对于所有其他按键,调用基类的处理
|
|
|
|
|
|
iDlgBase::keyPressEvent(event);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void nmWxEditWellPlot::onTimeDependentIconClicked()
|
|
|
|
|
|
{
|
|
|
|
|
|
if(!m_pNmDataWell) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
nmWxTimeDependentSkin::showForCurrentWell(m_pNmDataWell, this); // 传具体井数据
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void nmWxEditWellPlot::onTimeDependentCheckToggled(bool checked)
|
|
|
|
|
|
{
|
|
|
|
|
|
if(!m_pNmDataWell) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 更新数据模型
|
|
|
|
|
|
m_pNmDataWell->setTimeDependentSkin(checked);
|
|
|
|
|
|
|
|
|
|
|
|
nmWxNumericalDesign::notifyTimeDependentSkinChanged(m_pNmDataWell->getWellName(), checked);
|
|
|
|
|
|
}
|