diff --git a/Bin/Config/Lang/cn/nmNum_cn.qm b/Bin/Config/Lang/cn/nmNum_cn.qm index 2f93ad6..43deca2 100644 Binary files a/Bin/Config/Lang/cn/nmNum_cn.qm and b/Bin/Config/Lang/cn/nmNum_cn.qm differ diff --git a/Bin/Config/Lang/cn/nmNum_cn.ts b/Bin/Config/Lang/cn/nmNum_cn.ts index 2ff54ab..f02d5d3 100644 --- a/Bin/Config/Lang/cn/nmNum_cn.ts +++ b/Bin/Config/Lang/cn/nmNum_cn.ts @@ -5057,6 +5057,14 @@ Please check your input coordinates. Main options 主选项 + + View well result + 查看井结果 + + + Current well: + 当前井: + Include other wells 包含其他井 diff --git a/Include/nmNum/nmSubWnd/nmSubWndMain.h b/Include/nmNum/nmSubWnd/nmSubWndMain.h index a30c862..30c88c5 100644 --- a/Include/nmNum/nmSubWnd/nmSubWndMain.h +++ b/Include/nmNum/nmSubWnd/nmSubWndMain.h @@ -21,8 +21,6 @@ class nmCalculationDllPebiSolverTask; class QWidget; class QObject; -#include "nmWxSelectResultWellsDlg.h" - class NM_SUB_WND_EXPORT nmSubWndMain : public iSubWndBaseFit { Q_OBJECT @@ -224,9 +222,6 @@ class NM_SUB_WND_EXPORT nmSubWndMain : public iSubWndBaseFit { // 压力历史曲线数据 bool initPreHistory(QVector> & vvecHistoryData, QVector& vecDescs,bool isHistoryData); - // 查看一口井的结果数据 - void viewWellData(); - // 根据原始压力数据、计算出半对数、双对数数据 //void calculationLogData(nmDataWellBase* pWellData,QVector>& vvecHistoryData,QVector>& vvecLogPreData,QVector>& vvecSemiLogPreData); @@ -238,8 +233,6 @@ class NM_SUB_WND_EXPORT nmSubWndMain : public iSubWndBaseFit { // 锁定状态 bool m_lockState; - - nmWxSelectResultWellsDlg* m_resultDataDlg; // 查看结果井数据的对话框 QVector m_openDialogCmdIds; // 已打开对话框对应的命令ID iDockBaseWx* m_pWxDockParas; //模型参数 diff --git a/Include/nmNum/nmSubWxs/nmWxNumericalDesign.h b/Include/nmNum/nmSubWxs/nmWxNumericalDesign.h index 6ade40c..b71e326 100644 --- a/Include/nmNum/nmSubWxs/nmWxNumericalDesign.h +++ b/Include/nmNum/nmSubWxs/nmWxNumericalDesign.h @@ -33,10 +33,14 @@ public: // 静态方法,供外部调用以通知时间变表皮状态变化 static void notifyTimeDependentSkinChanged(const QString& wellName, bool checked); + // 刷新查看井结果下拉框 + static void notifyResultWellSelectorChanged(const QString& wellName = QString()); signals: void sigGenerateClicked(); // 点击生成按钮时发出的信号 void sigIncludeWells(); // 包含其他井后刷新参数栏的信号 + // 切换查看井结果时发出的信号 + void sigResultWellChanged(const QString& wellName); //void sigUpdateWellPlot(nmDataAnalyzeManager*); // 更新井图元 //void sigIncludeWells(); // 包含其他井后刷新参数栏的信号 @@ -63,6 +67,8 @@ signals: //void onIgnoreCheckToggled(bool checked); // 处理 Output result fields 复选框的切换 void onOutputResultFieldsToggled(bool checked); + // 查看井结果下拉框切换槽 + void onResultWellChanged(int index); // 处理时间参考系单选按钮切换 //void onTimeReferenceSystemToggled(bool checked); @@ -78,6 +84,8 @@ signals: private: // 初始化UI组件的私有函数 void initMainOptionsGroup(); // 初始化主选项组 + // 初始化查看井结果组 + void initResultWellGroup(); void initOutputGroup(); // 初始化输出组 (新) void initAdvancedGroup(); // 初始化高级组 (新) void initTimeSteppingGroup(); // 初始化时间步进组 @@ -89,6 +97,8 @@ private: void updateUiFromData(); // 根据UI更新模型数据 void updateDataFromUi(); + // 填充查看井结果下拉框 + void fillResultWellCombo(const QString& selectedWellName = QString()); private: @@ -101,6 +111,11 @@ private: QPushButton* m_pResetDiagnosticButton; // "从诊断复位"按钮 (新) QPushButton* m_pResetAnalyticalButton; // "从解析复位"按钮 (新) + // 查看井结果切换控件 + QGroupBox* m_pResultWellGroup; + QComboBox* m_pResultWellCombo; + bool m_bFillingResultWellCombo; + // 输出组组件 (新) QGroupBox* m_pOutputGroup; // 输出分组框 QCheckBox* m_pOutputResultFieldsCheck; // 输出结果文件复选框 diff --git a/Src/nmNum/nmSubWnd/nmSubWndMain.cpp b/Src/nmNum/nmSubWnd/nmSubWndMain.cpp index 6b834dc..dfc3a5f 100644 --- a/Src/nmNum/nmSubWnd/nmSubWndMain.cpp +++ b/Src/nmNum/nmSubWnd/nmSubWndMain.cpp @@ -66,8 +66,8 @@ #include "nmSingalCenter.h" -#include "nmWxSelectResultWellsWidget.h" #include "nmWxResultParameters.h" +#include "nmWxNumericalDesign.h" #include "nmWxReservoirProperties.h" @@ -120,7 +120,6 @@ nmSubWndMain::nmSubWndMain(QWidget *parent, QString sExt) : setWindowTitle(tr("nmSubWndMain")); m_lockState = false; // 默认为false - m_resultDataDlg = nullptr; m_openDialogCmdIds.clear(); m_pProgressDlg = nullptr; m_pSolverTask = nullptr; @@ -159,11 +158,6 @@ nmSubWndMain::~nmSubWndMain() // } //} - if(m_resultDataDlg != nullptr) { - delete m_resultDataDlg; - m_resultDataDlg = nullptr; - } - if (m_pFakeProgressTimer) { m_pFakeProgressTimer->stop(); // 因为构造时传了 this,这里不 delete 也可以,但 disconnect 是安全的 @@ -1454,12 +1448,6 @@ void nmSubWndMain::generationMesh() void nmSubWndMain::solveAndAnalyze() { - // 关闭查看井数据对话框 - if(m_resultDataDlg != nullptr) { - delete m_resultDataDlg; - m_resultDataDlg = nullptr; - } - // 强制清理旧的(以防万一上次没删掉) if (m_pProgressDlg != nullptr) { delete m_pProgressDlg; @@ -1560,9 +1548,6 @@ void nmSubWndMain::triggerToolBarAction(int index) void nmSubWndMain::mergeAnaResultToFitting() { - // 渲染数据时弹出查看井数据的对话框 - viewWellData(); - //QMessageBox::information(this, tr("solver success"), tr("solver succeed!")); /*if (m_parameterPropertyWindow != nullptr) { @@ -1635,6 +1620,8 @@ void nmSubWndMain::mergeAnaResultToFitting() vvecLogPreData = pWellData->getResultLogLog(); vvecSemiLogPreData = pWellData->getResultSemiLog(); } + // 计算完成后同步查看井下拉框选中项 + nmWxNumericalDesign::notifyResultWellSelectorChanged(currentWellName); // 半对数 QVector vecHalfLog; @@ -2150,79 +2137,6 @@ void nmSubWndMain::onProgressUpdated(int progress) } } -void nmSubWndMain::viewWellData() -{ - // 1.获取当前查看井的井名(默认选中) - nmDataWellBase* pCurWellData = nmDataAnalyzeManager::getCurrentInstance()->getCurWellData(); - QString currentWellName; - - if(pCurWellData != nullptr) { - currentWellName = pCurWellData->getWellName(); - } - - // 2.找到计算了的井 - QVector> vecWellsOrder = nmDataAnalyzeManager::getCurrentInstance()->getCalculationWells(); - - // 统计真实参与计算的井数量,Unknow_Well 在这里是裂缝等非井项。 - int nWellCount = 0; - for(int i = 0; i < vecWellsOrder.size(); i++) { - if(vecWellsOrder[i].first != NM_WELL_MODEL::Unknow_Well) { - nWellCount++; - } - } - - // 释放内存 - if(m_resultDataDlg != nullptr) { - delete m_resultDataDlg; - m_resultDataDlg = nullptr; - } - - // 只有一口井时不需要弹出选择井窗口,直接结束选择流程。 - if(nWellCount <= 1) { - return; - } - - // 3.创建对话框和井列表控件 - m_resultDataDlg = new nmWxSelectResultWellsDlg; - nmWxSelectResultWellsWidget *wellListWidget = new nmWxSelectResultWellsWidget; - - // 4.添加所有参与计算的井 - for(int i = 0; i < vecWellsOrder.size(); i++) { - // 跳过裂缝 - if(vecWellsOrder[i].first == NM_WELL_MODEL::Unknow_Well) { - continue; - } - - wellListWidget->addItem(vecWellsOrder[i].second); - } - - // 5.设置当前选中的井 - if(nmDataAnalyzeManager::getCurrentInstance()->isContainsWellName(currentWellName)) { - // 当前井参与计算,直接选择当前井 - wellListWidget->setSelectedItem(currentWellName); - } else { - // 当前井没有参与计算,选择参与计算的第一口井 - wellListWidget->setSelectedItem(vecWellsOrder[0].second); - - for(int i = 0; i < vecWellsOrder.size(); i++) { - // 跳过裂缝 - if(vecWellsOrder[i].first == NM_WELL_MODEL::Unknow_Well) { - continue; - } - - wellListWidget->setSelectedItem(vecWellsOrder[i].second); - break; - } - } - - // 6.设置控件并连接信号 - m_resultDataDlg->setWidget(wellListWidget); - connect(m_resultDataDlg, SIGNAL(wellSelected(QString)), this, SLOT(onWellSelected(QString))); - - // 7.显示对话框 - m_resultDataDlg->show(); -} - void nmSubWndMain::onWellSelected(const QString& wellName) { nmDataAnalyzeManager* pInstance = nmDataAnalyzeManager::getCurrentInstance(); diff --git a/Src/nmNum/nmSubWnd/nmSubWndUtils.cpp b/Src/nmNum/nmSubWnd/nmSubWndUtils.cpp index c012ce2..af69b6e 100644 --- a/Src/nmNum/nmSubWnd/nmSubWndUtils.cpp +++ b/Src/nmNum/nmSubWnd/nmSubWndUtils.cpp @@ -595,6 +595,9 @@ bool nmSubWndUtils::fillNmDockWxs(iSubWnd* pSubWnd) // 建立求解调用连接 connect(pAnalWx, SIGNAL(sigGenerateClicked()), pSubWndMain, SLOT(onGenerateButtonClicked())); + // 切换查看井结果时刷新曲线窗口 + connect(pAnalWx, SIGNAL(sigResultWellChanged(QString)), + pSubWndMain, SLOT(onWellSelected(QString))); // 建立更新参数栏连接 //connect(pAnalWx, SIGNAL(sigIncludeWells()), @@ -806,6 +809,8 @@ bool nmSubWndUtils::loadRsts(iSubWnd* pSubWnd, \ pDataManager->loadNmResult(sDir); // 加载当前分析中的PVT数据 pDataManager->initPvtParaFromSubFit(); + // 成果加载完成后刷新查看井下拉框 + nmWxNumericalDesign::notifyResultWellSelectorChanged(); // 切换左侧参数视图 pSubWndF->swapAnaNmDocks(true); @@ -841,6 +846,9 @@ bool nmSubWndUtils::loadRsts(iSubWnd* pSubWnd, \ // 建立求解调用连接 connect(pAnalWx, SIGNAL(sigGenerateClicked()), pSubWndMain, SLOT(onGenerateButtonClicked())); + // 切换查看井结果时刷新曲线窗口 + connect(pAnalWx, SIGNAL(sigResultWellChanged(QString)), + pSubWndMain, SLOT(onWellSelected(QString))); // 建立更新参数栏连接 connect(pAnalWx, SIGNAL(sigIncludeWells()), pParaWx, SLOT(onUpdate())); diff --git a/Src/nmNum/nmSubWxs/nmWxNumericalDesign.cpp b/Src/nmNum/nmSubWxs/nmWxNumericalDesign.cpp index 04ee7c0..2dd8dce 100644 --- a/Src/nmNum/nmSubWxs/nmWxNumericalDesign.cpp +++ b/Src/nmNum/nmSubWxs/nmWxNumericalDesign.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -45,6 +46,9 @@ nmWxNumericalDesign::nmWxNumericalDesign(QWidget *parent) { // 设置当前实例为静态指针 s_pCurrentInstance = this; + m_pResultWellGroup = nullptr; + m_pResultWellCombo = nullptr; + m_bFillingResultWellCombo = false; // 初始化图标路径 m_sIconDir = QCoreApplication::applicationDirPath(); @@ -65,6 +69,7 @@ nmWxNumericalDesign::nmWxNumericalDesign(QWidget *parent) // 初始化所有UI组件 initMainOptionsGroup(); // 初始化主选项组 + initResultWellGroup(); initOutputGroup(); // 初始化输出组 (新) initAdvancedGroup(); // 初始化高级组 (新) initTimeSteppingGroup(); // 初始化时间步进组 @@ -73,6 +78,7 @@ nmWxNumericalDesign::nmWxNumericalDesign(QWidget *parent) // 将各个组添加到滚动区域的布局中 pScrollLayout->addWidget(m_pMainOptionsGroup); + pScrollLayout->addWidget(m_pResultWellGroup); pScrollLayout->addWidget(m_pOutputGroup); pScrollLayout->addWidget(m_pAdvancedGroup); pScrollLayout->addWidget(m_pTimeSteppingGroup); @@ -118,6 +124,85 @@ nmWxNumericalDesign::~nmWxNumericalDesign() } } +// 外部刷新当前查看井下拉框 +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(); + } + } + + 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); @@ -517,6 +602,7 @@ void nmWxNumericalDesign::setupConnections() { // 连接生成按钮的点击信号到槽函数 connect(m_pGenerateButton, SIGNAL(clicked()), this, SLOT(onGenerateClicked())); + connect(m_pResultWellCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(onResultWellChanged(int))); // 主选项组连接 // 连接齿轮图标按钮的槽函数 @@ -596,6 +682,30 @@ void nmWxNumericalDesign::onTimeDependentCheck(bool 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(); @@ -768,6 +878,7 @@ void nmWxNumericalDesign::onOptionsIconClicked() // 刷新下侧参数栏 //emit sigIncludeWells(); nmWxParameterProperty::notifyUpdateTable(); + fillResultWellCombo(sCurrentWell); } }