#include "nmWxWellboreStorageCalculator.h" #include #include #include #include #include #include #include #include #include #include #include #include "nmWxWellboreStorageCalculatorVolume.h" #include "nmWxWellboreStorageCalculatorTubingData.h" nmWxWellboreStorageCalculator::nmWxWellboreStorageCalculator(QWidget *parent) : iDlgBase(parent) { this->initUI(); this->initConnections(); // 默认选中第一个模式 m_pModeButtonGroup->button(0)->setChecked(true); m_pStackedWidget->setCurrentIndex(0); // 默认计算第一种模式 calculateWellboreStorage(0); m_pTestedVolumeDialog = nullptr; m_pTubingDataDialog = nullptr; } nmWxWellboreStorageCalculator::~nmWxWellboreStorageCalculator() { } void nmWxWellboreStorageCalculator::initUI() { setWindowTitle(tr("Wellbore Storage Calculator")); // 设置一个稍大的固定窗口尺寸,以容纳所有组件并保持对齐 setFixedSize(500, 320); // 1. 创建模式选择的单选按钮和分组 m_pClosedChamberRadio = new QRadioButton(tr("Closed chamber")); m_pChangingLiquidLevelRadio = new QRadioButton(tr("Changing liquid level")); m_pModeButtonGroup = new QButtonGroup(this); m_pModeButtonGroup->addButton(m_pClosedChamberRadio, 0); m_pModeButtonGroup->addButton(m_pChangingLiquidLevelRadio, 1); m_pModeGroupBox = new QGroupBox(tr("Calculation Mode")); QVBoxLayout* modeLayout = new QVBoxLayout; modeLayout->addWidget(m_pClosedChamberRadio); modeLayout->addWidget(m_pChangingLiquidLevelRadio); m_pModeGroupBox->setLayout(modeLayout); // 2. 创建用于切换页面的 QStackedWidget 和两个页面 m_pStackedWidget = new QStackedWidget(this); m_pClosedChamberPage = new QWidget; m_pChangingLiquidLevelPage = new QWidget; // 3. 为密闭井筒页面布局 m_pTestedVolumeLabel = new QLabel(tr("Tested volume:")); m_pTestedVolumeEdit = new QLineEdit; m_pTestedVolumeUnitCombo = new QComboBox; m_pTestedVolumeEdit->setValidator(new QDoubleValidator(this)); // 设置默认值和单位 m_pTestedVolumeEdit->setText("0.317975"); m_pTestedVolumeUnitCombo->addItem(tr("m^3")); //m_pTestedVolumeUnitCombo->addItem(tr("ft^3")); //m_pTestedVolumeUnitCombo->addItem(tr("bbl")); // 创建密闭井筒模式下的计算按钮 m_pClosedChamberCalculateButton = new QPushButton(); QString sIconDir = QCoreApplication::applicationDirPath(); sIconDir = sIconDir.section('/', 0, -2); // 获取上一级目录 sIconDir += "/Res/Icon/"; m_pClosedChamberCalculateButton->setIcon(QIcon(sIconDir + "NmWellboreStorageCalculator.png")); m_pClosedChamberCalculateButton->setIconSize(QSize(32, 32)); m_pClosedChamberCalculateButton->setFixedSize(34, 34); m_pFluidCompressibilityLabel = new QLabel(tr("Fluid compressibility:")); m_pFluidCompressibilityEdit = new QLineEdit; m_pFluidCompressibilityUnitCombo = new QComboBox; m_pFluidCompressibilityEdit->setValidator(new QDoubleValidator(this)); // 设置默认值和单位 m_pFluidCompressibilityEdit->setText("0.725189"); m_pFluidCompressibilityUnitCombo->addItem(tr("1/Mpa")); //m_pFluidCompressibilityUnitCombo->addItem(tr("1/psi")); m_pClosedChamberLayout = new QGridLayout; // 为列设置拉伸因子以保持对齐和宽度一致 m_pClosedChamberLayout->setColumnStretch(0, 1); // Label列 m_pClosedChamberLayout->setColumnStretch(1, 2); // LineEdit列 m_pClosedChamberLayout->setColumnStretch(2, 1); // ComboBox列 m_pClosedChamberLayout->setColumnStretch(3, 1); // Button列 m_pClosedChamberLayout->addWidget(m_pTestedVolumeLabel, 0, 0); m_pClosedChamberLayout->addWidget(m_pTestedVolumeEdit, 0, 1); m_pClosedChamberLayout->addWidget(m_pTestedVolumeUnitCombo, 0, 2); // 将计算按钮添加到第一行第三列 m_pClosedChamberLayout->addWidget(m_pClosedChamberCalculateButton, 0, 3, Qt::AlignRight); m_pClosedChamberLayout->addWidget(m_pFluidCompressibilityLabel, 1, 0); m_pClosedChamberLayout->addWidget(m_pFluidCompressibilityEdit, 1, 1); m_pClosedChamberLayout->addWidget(m_pFluidCompressibilityUnitCombo, 1, 2); m_pClosedChamberPage->setLayout(m_pClosedChamberLayout); // 4. 为液面变化页面布局 m_pTubingIdLabel = new QLabel(tr("Tubing I.D.:")); m_pTubingIdEdit = new QLineEdit; m_pTubingIdUnitCombo = new QComboBox; m_pTubingIdEdit->setValidator(new QDoubleValidator(this)); // 设置默认值和单位 m_pTubingIdEdit->setText("0.09144"); m_pTubingIdUnitCombo->addItem(tr("m")); //m_pTubingIdUnitCombo->addItem(tr("ft")); //m_pTubingIdUnitCombo->addItem(tr("in")); // 创建液面变化模式下的计算按钮 m_pChangingLiquidLevelCalculateButton = new QPushButton(); m_pChangingLiquidLevelCalculateButton->setIcon(QIcon(sIconDir + "NmWellboreStorageCalculator.png")); m_pChangingLiquidLevelCalculateButton->setIconSize(QSize(32, 32)); m_pChangingLiquidLevelCalculateButton->setFixedSize(34, 34); m_pFluidDensityLabel = new QLabel(tr("Fluid density:")); m_pFluidDensityEdit = new QLineEdit; m_pFluidDensityUnitCombo = new QComboBox; m_pFluidDensityEdit->setValidator(new QDoubleValidator(this)); // 设置默认值和单位 m_pFluidDensityEdit->setText("1000.00"); m_pFluidDensityUnitCombo->addItem(tr("kg/m^3")); //m_pFluidDensityUnitCombo->addItem(tr("lb/ft^3")); //m_pFluidDensityUnitCombo->addItem(tr("lb/bbl")); m_pChangingLiquidLevelLayout = new QGridLayout; // 为列设置拉伸因子以保持对齐和宽度一致 m_pChangingLiquidLevelLayout->setColumnStretch(0, 1); // Label列 m_pChangingLiquidLevelLayout->setColumnStretch(1, 2); // LineEdit列 m_pChangingLiquidLevelLayout->setColumnStretch(2, 1); // ComboBox列 m_pChangingLiquidLevelLayout->setColumnStretch(3, 1); // Button列 m_pChangingLiquidLevelLayout->addWidget(m_pTubingIdLabel, 0, 0); m_pChangingLiquidLevelLayout->addWidget(m_pTubingIdEdit, 0, 1); m_pChangingLiquidLevelLayout->addWidget(m_pTubingIdUnitCombo, 0, 2); // 将计算按钮添加到第一行第三列 m_pChangingLiquidLevelLayout->addWidget(m_pChangingLiquidLevelCalculateButton, 0, 3, Qt::AlignRight); m_pChangingLiquidLevelLayout->addWidget(m_pFluidDensityLabel, 1, 0); m_pChangingLiquidLevelLayout->addWidget(m_pFluidDensityEdit, 1, 1); m_pChangingLiquidLevelLayout->addWidget(m_pFluidDensityUnitCombo, 1, 2); m_pChangingLiquidLevelPage->setLayout(m_pChangingLiquidLevelLayout); m_pStackedWidget->addWidget(m_pClosedChamberPage); m_pStackedWidget->addWidget(m_pChangingLiquidLevelPage); // 5. 创建公共部分和按钮 m_pWellboreStorageLabel = new QLabel(tr("Wellbore storage:")); m_pWellboreStorageEdit = new QLineEdit; m_pWellboreStorageEdit->setReadOnly(true); m_pWellboreStorageUnitCombo = new QComboBox; // 井筒储集系数的默认单位 m_pWellboreStorageUnitCombo->addItem(tr("m^3/Mpa")); //m_pWellboreStorageUnitCombo->addItem(tr("bbl/psi")); m_pRefreshButton = new QPushButton(); m_pRefreshButton->setIcon(QIcon(sIconDir + "NmWellboreStorageRefresh.png")); m_pRefreshButton->setIconSize(QSize(32, 32)); m_pRefreshButton->setFixedSize(34, 34); m_pOkButton = new QPushButton(tr("OK")); m_pCancelButton = new QPushButton(tr("Cancel")); QHBoxLayout* buttonLayout = new QHBoxLayout; buttonLayout->addStretch(); buttonLayout->addWidget(m_pOkButton); buttonLayout->addWidget(m_pCancelButton); // 6. 主布局 m_pMainLayout = new QVBoxLayout(this); m_pMainLayout->addWidget(m_pModeGroupBox); m_pMainLayout->addWidget(m_pStackedWidget); QGridLayout* commonLayout = new QGridLayout; // 为列设置拉伸因子以保持对齐和宽度一致 // commonLayout->setColumnStretch(0, 1); // commonLayout->setColumnStretch(1, 2); // commonLayout->setColumnStretch(2, 1); // commonLayout->setColumnStretch(3, 1); commonLayout->addWidget(m_pWellboreStorageLabel, 0, 0); commonLayout->addWidget(m_pWellboreStorageEdit, 0, 1); commonLayout->addWidget(m_pWellboreStorageUnitCombo, 0, 2); commonLayout->addWidget(m_pRefreshButton, 0, 3); m_pMainLayout->addLayout(commonLayout); m_pMainLayout->addLayout(buttonLayout); } void nmWxWellboreStorageCalculator::initConnections() { // 连接模式按钮组的信号到槽,实现页面切换 connect(m_pModeButtonGroup, SIGNAL(buttonClicked(int)), this, SLOT(onModeChanged(int))); // 连接两个计算按钮到各自的槽函数 connect(m_pClosedChamberCalculateButton, SIGNAL(clicked()), this, SLOT(onClosedChamberCalculateClicked())); connect(m_pChangingLiquidLevelCalculateButton, SIGNAL(clicked()), this, SLOT(onChangingLiquidLevelCalculateClicked())); // 连接刷新按钮 connect(m_pRefreshButton, SIGNAL(clicked()), this, SLOT(onRefreshWellboreStorageClicked())); // 连接OK和Cancel按钮 connect(m_pOkButton, SIGNAL(clicked()), this, SLOT(accept())); connect(m_pCancelButton, SIGNAL(clicked()), this, SLOT(reject())); } // 实现槽函数 void nmWxWellboreStorageCalculator::onModeChanged(int id) { // 根据按钮的ID来切换 QStackedWidget 的页面 m_pStackedWidget->setCurrentIndex(id); } void nmWxWellboreStorageCalculator::onRefreshWellboreStorageClicked() { // 根据当前显示的页面,触发相应的计算 int currentMode = m_pStackedWidget->currentIndex(); calculateWellboreStorage(currentMode); } void nmWxWellboreStorageCalculator::calculateWellboreStorage(int mode) { double wellboreStorage = 0.0; bool ok = false; // 计算常数 const double G = 9.80665; // 重力加速度,m/s^2 const double MPA_TO_PA = 1.0e6; // 1 MPa = 10^6 Pa if (mode == 0) // 密闭井筒模式,输入单位为 m^3 和 1/Mpa { double testedVolume = m_pTestedVolumeEdit->text().toDouble(&ok); if (!ok) { return; } double fluidCompressibility = m_pFluidCompressibilityEdit->text().toDouble(&ok); if (!ok) { return; } // C = V_test * C_f // V_test 单位: m^3 // C_f 单位: 1/Mpa wellboreStorage = testedVolume * fluidCompressibility; } else if (mode == 1) // 液面变化模式,输入单位为 m 和 kg/m^3 { double tubingId = m_pTubingIdEdit->text().toDouble(&ok); if (!ok) { return; } double fluidDensity = m_pFluidDensityEdit->text().toDouble(&ok); if (!ok || fluidDensity == 0) { return; } // 计算井筒截面积 A,单位 m^2 const double PI = acos(-1.0); double wellboreArea = PI * pow(tubingId / 2.0, 2.0); // C = A / (rho * g),结果单位为 m^3/Pa double storageInPa = wellboreArea / (fluidDensity * G); // 将结果从 m^3/Pa 转换为 m^3/Mpa wellboreStorage = storageInPa * MPA_TO_PA; } m_pWellboreStorageEdit->setText(QString::number(wellboreStorage)); } double nmWxWellboreStorageCalculator::getWellboreStorageValue() const { bool ok; double value = m_pWellboreStorageEdit->text().toDouble(&ok); if (ok && value >= 0) { return value; } // 如果转换失败,返回-1 return -1; } void nmWxWellboreStorageCalculator::onClosedChamberCalculateClicked() { if (!m_pTestedVolumeDialog) { // 创建对话框实例,并指定父对象为 this m_pTestedVolumeDialog = new nmWxWellboreStorageCalculatorVolume(this); } // 以模态对话框方式运行 if (m_pTestedVolumeDialog->exec() == QDialog::Accepted) { // 获取计算后的井筒储集系数 double dV = m_pTestedVolumeDialog->getCalculatedVolume(); if (dV != -1) { // 应用到测试体积的值 m_pTestedVolumeEdit->setText(QString::number(dV)); } } } void nmWxWellboreStorageCalculator::onChangingLiquidLevelCalculateClicked() { if (!m_pTubingDataDialog) { // 创建对话框实例,并指定父对象为 this m_pTubingDataDialog = new nmWxWellboreStorageCalculatorTubingData(this); } // 以模态对话框方式运行 if (m_pTubingDataDialog->exec() == QDialog::Accepted) { // 获取选中的油管规格 double dSlectedTubingID = m_pTubingDataDialog->getSelectedTubingID(); // 检查值是否有效,然后更新主界面的输入框 if (dSlectedTubingID != -1.0) { m_pTubingIdEdit->setText(QString::number(dSlectedTubingID)); } } }