#include "zxLogInstance.h" #include "iRibbonXmlCmd.h" #include #include "zxSysUtils.h" #include "ZxUiBase.h" #include "ZxMainWindow.h" #include "ZxTabWidget.h" #include "TreeWxMain.h" #include "iDockBaseWx.h" #include "iModuleHelper.h" #include "ZxDataWell.h" #include "ZxDataProject.h" #include "nmFrameworkTest.h" #include "iSubWndFitting.h" #ifdef MY_OWN_GRID #include "iSubWndGrid.h" #else #include "nmSubWndDemo.h" #endif #include "nmSubWndUtils.h" #include "nmSubWndMain.h" #include "nmSubWndGrid.h" #include "nmSubWndPostprocessing.h" #include "nmWxGridDlg.h" #include "nmWxPostprocessingAnimationWidget.h" #include "nmGuiPlot.h" #include "ZxObjBase.h" #include "nmDataAnalyzeManager.h" #include "iRibbonXmlTab.h" #include "nmWxParameterProperty.h" #include "nmWxNumericalDesign.h" #include "nmDataOutline.h" #include "ZxRstWnd.h" #include "nmWxChangeAnal.h" #include "nmDataAxis.h" namespace { // 判断指定相态下是否至少有一个PVT曲线结果 bool hasPvtCurve(iSubWndFitting* pSubWndF, PvtFluidType eType, const QStringList& listParas) { if(pSubWndF == nullptr) { return false; } for(int i = 0; i < listParas.size(); ++i) { VecDouble vecX; QVector vecY; pSubWndF->getPvtRstOf(eType, listParas[i], vecX, vecY); if(!vecX.isEmpty()) { return true; } } return false; } } nmSubWndUtils* nmSubWndUtils::getInstance() { static nmSubWndUtils s_instance; // 在第一次调用时创建唯一实例 return &s_instance; } nmSubWndUtils::nmSubWndUtils() { m_pMainWnd = nullptr; m_pTabWx = nullptr; } nmSubWndUtils::~nmSubWndUtils() {} iSubWnd* nmSubWndUtils::createSubWnd(const iRibbonXmlCmd* pCmdInfo, \ const ZxMainWindow* pMainWnd, \ bool& bCreatedNewOne) { if (nullptr == pCmdInfo) { return nullptr; } // TODO 此处是自行控制是否单一模式 bool bOnlyOneForCurTabWx = true; return makesureSubWnd(pCmdInfo->m_sID, pCmdInfo->m_sExtInfo, \ pMainWnd, bCreatedNewOne, \ bOnlyOneForCurTabWx); } iSubWnd* nmSubWndUtils::makesureSubWnd(QString sID, QString sExt, \ const ZxMainWindow* pMainWnd, \ bool& bCreatedNewOne, \ bool bOnlyOneForCurTabWx /*= true*/) { Q_ASSERT (nullptr != pMainWnd); //单一模式,则先查找,如果已经存在,则直接返回 if (bOnlyOneForCurTabWx) { ZxMainWindow* pMainWnd1 = const_cast(pMainWnd); ZxTabWidget* pTabWx = pMainWnd1->getCurTabWx(); //仅仅在当前TabWx下查找,此处可以根据需要调整 if (nullptr != pTabWx) { for (int i = 0; i < pTabWx->count(); i++) { iSubWnd* pSubWnd = dynamic_cast(pTabWx->widget(i)); if (nullptr != pSubWnd) { if (_isSame(sID, pSubWnd->getWndID())) { bCreatedNewOne = false; // TODO 根据需要,是否需要激活当前 if (i != pTabWx->currentIndex()) { pTabWx->setCurrentIndex(i); } return pSubWnd; } } } } } // 创建新的 bCreatedNewOne = true; iSubWnd* pSubWnd = nullptr; // Here is your own codes int nID = sID.toInt(); if(nID == 5118) { // TODO:提示应该先打开一个分析 //QMessageBox::information(pSubWnd, tr("error"), tr("please open an analyze!")); // 判断油藏参数是否已经初始化 //if(nmDataAnalyzeManager::getCurrentInstance()->getReservoirData() == nullptr) { // // 初始化油藏参数 // nmDataAnalyzeManager::getCurrentInstance()->createReservoir(); // // 初始化PVT // nmDataAnalyzeManager::getCurrentInstance()->initPvtParaFromSubFit(); //} // 1、获取当前窗体下的所有流动段分析 // 选择一个流动段分析里的数据作为当前地图要展示的数据 // TODO:2、没有流动段分析 if(nmDataAnalyzeManager::getCurrentFitting() != nullptr) { nmSubWndMain* pSubWndMain = new nmSubWndMain(NULL, sExt); pSubWnd = pSubWndMain; } else { ZxMainWindow* pMainWnd1 = const_cast(pMainWnd); QMessageBox::information(pMainWnd1, tr("No Data"), tr("please open an Fitting and click Numerical button")); } } else if(nID == 5114) { // PEBI GridControl控制参数,对应HX_NWTM_GRID_INPUT::GridControl double dPebiGridControl = 150.0; bool bGeneratePebiGrid = true; // 判断是否是加载进来的数据,如果不是加载进来的,则需要添加设置网格信息的对话框 if(!nmDataAnalyzeManager::getCurrentInstance()->m_bIsLoadData) { // 当前只保留PEBI网格,弹窗只需要设置GridControl nmWxGridDlg dlg(&dPebiGridControl); if(dlg.exec() == QDialog::Rejected) { return NULL; } } else { // 更新标志 nmDataAnalyzeManager::getCurrentInstance()->m_bIsLoadData = false; bGeneratePebiGrid = false; } // 创建PEBI网格窗口;新建数据时生成网格,加载数据时直接展示已加载结果。 nmSubWndGrid* pSubWndGrid = new nmSubWndGrid(NULL, sExt, dPebiGridControl, bGeneratePebiGrid); disconnect(nmDataAnalyzeManager::getCurrentInstance(), SIGNAL(dataChanged()), pSubWndGrid, SLOT(updateGrid())); connect(nmDataAnalyzeManager::getCurrentInstance(), SIGNAL(dataChanged()), pSubWndGrid, SLOT(updateGrid()), Qt::QueuedConnection); pSubWnd = pSubWndGrid; } else if(nID == 5116) { // 后处理 nmSubWndPostprocessing* pSubWndPostProcessing = new nmSubWndPostprocessing(NULL, sExt); pSubWnd = pSubWndPostProcessing; } if(NULL != pSubWnd) { // TODO 此处根据需要设置 改变 标识 pSubWnd->setModified(true); } return pSubWnd; } bool nmSubWndUtils::runCmdBySpecial(const iRibbonXmlCmd* pCmdInfo, \ const ZxMainWindow* pMainWnd) { //nmSubWndUtils* pUtilsInstance = nmSubWndUtils::getInstance(); // 第一次创建,TODO:或者打开另一个窗体时连接槽函数,避免多次调用 //if (pUtilsInstance->m_pMainWnd == nullptr || pUtilsInstance->m_pMainWnd != pMainWnd) //{ // // 第一次操作时连接tab的槽函数 // ZxMainWindow* pMainWnd1 = const_cast(pMainWnd); // if (nullptr != pMainWnd1) // { // pUtilsInstance->m_pMainWnd = pMainWnd1; // ZxTabWidget* pTabWx = pMainWnd1->getCurTabWx(); // if (nullptr != pTabWx){ // disconnect(pTabWx, SIGNAL(currentChanged(int)), pUtilsInstance, SLOT(slotHandleTabChange(int))); // connect(pTabWx, SIGNAL(currentChanged(int)), pUtilsInstance, SLOT(slotHandleTabChange(int))); // } // } //} ZxMainWindow* pMainWnd1 = const_cast(pMainWnd); nmSubWndUtils* pUtilsInstance = nmSubWndUtils::getInstance(); if(nullptr != pMainWnd1) { ZxTabWidget* pTabWx = pMainWnd1->getCurTabWx(); if(nullptr != pTabWx) { if(pUtilsInstance->m_pTabWx == nullptr || pUtilsInstance->m_pTabWx != pTabWx) { pUtilsInstance->m_pTabWx = pTabWx; disconnect(pUtilsInstance->m_pTabWx, SIGNAL(currentChanged(int)), pUtilsInstance, SLOT(slotHandleTabChange(int))); connect(pUtilsInstance->m_pTabWx, SIGNAL(currentChanged(int)), pUtilsInstance, SLOT(slotHandleTabChange(int))); } } } if(nullptr == pCmdInfo) { return false; } // 20250310 测试Release崩溃问题,暂时放开 //#ifdef QT_DEBUG // 专门提供给数值模块,进行一些框架代码的调试 if (_isSame(pCmdInfo->m_sID, "5999")) { nmFrameworkTest::testFrmCodes(pCmdInfo, pMainWnd); return true; } //#endif return runCmdBySpecial(pCmdInfo->m_sID, pCmdInfo->m_sExtInfo, pMainWnd); } bool nmSubWndUtils::runCmdBySpecial(QString sID, QString sExt, \ const ZxMainWindow* pMainWnd) { // Here is your own codes if(_isSame(sID, "12345")) { QMessageBox::information(nullptr, zxAppDescEN, QObject::tr("I am abc")); return true; } if(_isSame(sID, "5130")) { ZxMainWindow* pMainWnd1 = const_cast(pMainWnd); // 创建并显示对话框 nmWxChangeAnal analChangeDlg(nullptr, pMainWnd1); // 执行对话框并判断返回值 if(analChangeDlg.exec() == QDialog::Accepted) { } return true; } else { return false; } } bool nmSubWndUtils::isEnableOfID_Common(QString sID, QString sName, \ const bool bLicensed, \ const ZxMainWindow* pMainWnd) { // 20250310 测试Release崩溃问题,暂时放开 //#ifdef QT_DEBUG // 专门提供给数值模块,进行一些框架代码的调试 if (_isSame(sID, "5999")) { return (true); } //#endif bool b1 = (nullptr != zxCurProject); // Here is your own codes if (_isSame(sID, "5101")) { return (true); } else if (_isSame(sID, "5002")) //或者 _isSame(sName, "PropertyLoad") { // (pMainWnd); if (nullptr != pMainWnd1) { iSubWnd* pSubWnd = pMainWnd1->getCurSubWnd(); //当前窗体 if (nullptr != pSubWnd) { QString sCurID = pSubWnd->getWndID(); bOk = (_isSame(sCurID, "3003") || _isSame(sCurID, "3004") // || _isSame(sCurID, "6001") //TODO 这是试井设计页面,待定 ); } } return bOk; } else if(_isSame(sName, "NmMap")) { return (b1 && bLicensed); } else if(_isSame(sName, "NmAnalChange")) { return (b1 && bLicensed); } else { return false; } } bool nmSubWndUtils::dealwithRibbonTab(iRibbonXmlTab* pTab, \ const ZxMainWindow* pMainWnd) { return false; //your own codes } bool nmSubWndUtils::fillNmDockWxs(iSubWnd* pSubWnd) { iSubWndFitting* pSubWndF = dynamic_cast(pSubWnd); Q_ASSERT(nullptr != pSubWndF); if(pSubWndF == nullptr) { return false; } // 如果当前分析没有对应相态的PVT相关参数,提示并返回 //PvtFluidType eType = pSubWndF->getBasicPft(); //bool bHasPvtData = false; //if(eType == WFT_Oil) { // bHasPvtData = hasPvtCurve(pSubWndF, WFT_Oil, QStringList() << "Rs" << "Bo" << "Co" << "Rhoo" << "Miuo"); //} else if(eType == WFT_Gas) { // bHasPvtData = hasPvtCurve(pSubWndF, WFT_Gas, QStringList() << "Rv" << "Bg" << "Cg" << "Miug" << "Rhog" << "Zg"); //} else if(eType == WFT_Water) { // bHasPvtData = hasPvtCurve(pSubWndF, WFT_Water, QStringList() << "Rsw" << "Bw" << "Cw" << "Miuw" << "Rhow"); //} else if(eType == WFT_Oil_Water) { // bHasPvtData = hasPvtCurve(pSubWndF, WFT_Oil, QStringList() << "Rs" << "Bo" << "Co" << "Rhoo" << "Miuo") // || hasPvtCurve(pSubWndF, WFT_Water, QStringList() << "Rsw" << "Bw" << "Cw" << "Miuw" << "Rhow"); //} //if(!bHasPvtData) { // QString appDir = QCoreApplication::applicationDirPath(); // appDir = appDir.section('/', 0, -2); // 获取上一级目录 // QMessageBox msgBox; // msgBox.setWindowTitle(tr("PVT Data Missing")); // msgBox.setText(tr("Please check if PVT parameters have been calculated in the analysis.")); // msgBox.setIconPixmap(QPixmap(appDir + "/Res/Icon/NmPVTDataMissMessage.png")); // PVT 参数计算向导 // msgBox.setStandardButtons(QMessageBox::Ok); // msgBox.exec(); // return false; //} iDockBaseWx* pWxDockNm1 = pSubWndF->getNmDockWx(0); iDockBaseWx* pWxDockNm2 = pSubWndF->getNmDockWx(1); Q_ASSERT (nullptr != pWxDockNm1); Q_ASSERT (nullptr != pWxDockNm2); if (pWxDockNm1->widget() != nullptr && pWxDockNm2->widget() != nullptr) { return true; //已经设定的话,则不再处理 } // 获取当前井并检查类型是否支持 ZxDataWell* pWellData = zxCurWell; if(pWellData == nullptr) { return false; } QString wellClass = pWellData->getWellClassEn(); // 定义支持的井类型列表 QStringList supportedTypes; supportedTypes << "VerticalWell" << "VerticalFracturedWell" << "HorizontalMultiFracturedWell"; if (!supportedTypes.contains(wellClass)) { QMessageBox::warning(nullptr, tr("Unsupported Well Type"), tr("The current well type '%1' is not supported for numerical modeling.\n" "Supported types: Vertical, Vertical Fractured, and Horizontal Multi-Fractured Wells.") .arg(pWellData->getWellClassCn())); return false; } // 进入到这里,说明是新打开的流动段分析,所以需要动态创建数据管理中心 // 根据分析窗口创建唯一的数据管理对象 nmDataAnalyzeManager* pDataManager = nmDataAnalyzeManager::getInstanceByFitting(pSubWndF); Q_ASSERT(nullptr != pDataManager); if(pDataManager == nullptr) { return false; } // 设置当前分析窗体 nmDataAnalyzeManager::setCurrentFitting(pSubWndF); // TODO:初始化坐标轴相关信息 nmDataAxis* pAxisData = pDataManager->getAxisData(); if(pAxisData == nullptr) { pAxisData = new nmDataAxis; // 将 pAxisData 存入数据中心 nmDataAnalyzeManager::getCurrentInstance()->setAxisData(pAxisData); } // 读取解析解的参数 // 1.1 初始化油藏参数 pDataManager->createReservoir(); // 1.2 初始化PVT参数 pDataManager->initPvtParaFromSubFit(); // 1.3 初始化当前井数据 pDataManager->initCurWellData(); // 1.4 初始化边界数据 nmDataWellBase* pCurWell = pDataManager->getCurWellData(); Q_ASSERT(nullptr != pCurWell); if(pCurWell == nullptr) { return false; } double dX = pCurWell->getX().getValue().toDouble(); double dY = pCurWell->getY().getValue().toDouble(); // 解析解相关参数 QMap mapAnaParas; mapAnaParas.clear(); pSubWndF->getBrotherDockParas(mapAnaParas, false); Q_ASSERT(mapAnaParas.count() > 0); // 解析解边界类型 m_Bdy_Type oBdyType = BT_None; QString sKey = "Bdy"; if(mapAnaParas.contains(sKey)) { int n = mapAnaParas[sKey].toInt(); if(n <= (int)BT_Rect) { oBdyType = m_Bdy_Type(n); } } // 边界距离(是井点到四周的直线距离) if(oBdyType == BT_Rect || oBdyType == BT_Circle) { // 设置边界数据 if(oBdyType == BT_Rect) { // 矩形边界 VecDouble vecBdyDiss; vecBdyDiss.clear(); QStringList list; list << "ne" << "se" << "we" << "ee"; for(int i = 0; i < list.count(); i++) { QString s = list[i]; if(mapAnaParas.contains(s)) { vecBdyDiss << mapAnaParas[s].toDouble(); } } double top_dist = vecBdyDiss[0]; double right_dist = vecBdyDiss[1]; double bottom_dist = vecBdyDiss[2]; double left_dist = vecBdyDiss[3]; // 计算四个顶点的坐标 QPointF topLeft(dX - left_dist, dY + top_dist); // 左上角 QPointF topRight(dX + right_dist, dY + top_dist); // 右上角 QPointF bottomRight(dX + right_dist, dY - bottom_dist); // 右下角 QPointF bottomLeft(dX - left_dist, dY - bottom_dist); // 左下角 // 创建边界点集合 QVector vecBoundaryPoints; vecBoundaryPoints << topLeft << topRight << bottomRight << bottomLeft; // 创建矩形边界数据对象 nmDataOutline* pOutlineData = pDataManager->createOutline(); Q_ASSERT(pOutlineData); if(pOutlineData == nullptr) { return false; } // 设置默认边界名称 pOutlineData->setName(""); // 设置边界点 pOutlineData->setOutlinePoints(vecBoundaryPoints); // 设置边界类型 pOutlineData->setOutlineType(NM_Rect_Outline_Type); // 设置流型列表(假设全部为0) QVector vecFlowTypes(vecBoundaryPoints.size(), 0); pOutlineData->setFlowTypeList(vecFlowTypes); } else { // 圆形边界 QString s = "re"; double dRadius = 0.0; if(mapAnaParas.contains(s)) { dRadius = mapAnaParas[s].toDouble(); } // 创建圆形边界数据对象 nmDataOutline* pOutlineData = pDataManager->createOutline(); Q_ASSERT(pOutlineData); if(pOutlineData == nullptr) { return false; } // 设置默认边界名称 pOutlineData->setName(""); // 设置半径 pOutlineData->setRadius(dRadius); // 设置圆心 pOutlineData->setCenter(QPointF(dX, dY)); // 设置边界类型 pOutlineData->setOutlineType(NM_Data_Outline_Type::NM_Round_Outline_Type); // 设置流型列表(假设全部为0) QVector vecFlowTypes(1, 0); pOutlineData->setFlowTypeList(vecFlowTypes); // 创建存储点的向量 QVector vecPoints; // 放入圆心 vecPoints.append(QPointF(dX, dY)); // 放入半径 vecPoints.append(QPointF(dRadius, dRadius)); // 计算圆上的四个关键点并放入向量(上、右、下、左) vecPoints.append(QPointF(dX, dY - dRadius)); vecPoints.append(QPointF(dX + dRadius, dY)); vecPoints.append(QPointF(dX, dY + dRadius)); vecPoints.append(QPointF(dX - dRadius, dY)); // 添加到数据中 pOutlineData->setOutlinePoints(vecPoints); } } else { // 如果解析解这里没有设置边界,数值解设置默认边界 // 创建默认矩形边界数据对象 nmDataOutline* pDefaultOutlineData = pDataManager->createOutline(); Q_ASSERT(pDefaultOutlineData); if(pDefaultOutlineData == nullptr) { return false; } // 设置默认边界名称 pDefaultOutlineData->setName(""); // 设置边界点 QVector vecPoints; vecPoints << QPointF(-1000.00, 1000.00) << QPointF(1000.00, 1000.00) << QPointF(1000.00, -1000.00) << QPointF(-1000.00, -1000.00); pDefaultOutlineData->setOutlinePoints(vecPoints); // 设置边界类型 pDefaultOutlineData->setOutlineType(NM_Rect_Outline_Type); // 设置流型列表(假设全部为0) QVector vecFlowTypes(vecPoints.size(), 0); pDefaultOutlineData->setFlowTypeList(vecFlowTypes); } // 1.6 创建时间步设置相关数据 pDataManager->createTimeStep(); // 创建敏感性分析数据 pDataManager->createSensitiveData(); // TODO:创建nmSubWndMain的作用主要是因为求解函数在这个类里,后续应该拆分掉 nmSubWndMain* pSubWndMain = new nmSubWndMain(NULL, ""); ZxMainWindow* pMainWnd = pSubWndF->getMainWindow(); // 设置当前窗口到Map pSubWndMain->setMainWindow(pMainWnd); pWxDockNm1->setWindowTitle(tr("Generate numerical model")); //改变Title pWxDockNm2->setWindowTitle(tr("Parameters")); //QTextEdit* pWx1 = new QTextEdit("This is demo for upper"); //QTextEdit* pWx2 = new QTextEdit("This is demo for lower"); nmWxNumericalDesign* pAnalWx = new nmWxNumericalDesign(); nmWxParameterProperty* pParaWx = new nmWxParameterProperty(); // 建立求解调用连接 connect(pAnalWx, SIGNAL(sigGenerateClicked()), pSubWndMain, SLOT(onGenerateButtonClicked())); // 建立更新参数栏连接 //connect(pAnalWx, SIGNAL(sigIncludeWells()), // pParaWx, SLOT(onUpdate())); // 井图元更新连接 // connect(pAnalWx, SIGNAL(sigUpdateWellPlot(nmDataAnalyzeManager*)), // pSubWndMain, SLOT(slotUpdateWellPlotByDataManager(nmDataAnalyzeManager*))); // QTextEdit* pWx1 = new CustomParaWx("This is demo for upper"); // pWx1->... Q_ASSERT(nullptr != pAnalWx); Q_ASSERT(nullptr != pParaWx); pWxDockNm1->setWidget(pAnalWx); pWxDockNm2->setWidget(pParaWx); return true; //your own codes } bool nmSubWndUtils::getAnaDockParas(iSubWnd* pSubWnd) { iSubWndFitting* pSubWndF = dynamic_cast(pSubWnd); Q_ASSERT(nullptr != pSubWndF); if(pSubWndF == nullptr) { return false; } ////////////////////////////////////////////////////////////////// // 如下代码,请根据需要在合适位置借鉴参照编写 QMap mapAnaParas;//当前解析解的参数 mapAnaParas.clear(); pSubWndF->getBrotherDockParas(mapAnaParas, false); Q_ASSERT(mapAnaParas.count() > 0); // 解析解边界类型 m_Bdy_Type oBdyType = BT_None; QString sKey = "Bdy"; if (mapAnaParas.contains(sKey)) { int n = mapAnaParas[sKey].toInt(); if (n <= (int)BT_Rect) { oBdyType = m_Bdy_Type(n); } } // 边界距离(是井点到四周的直线距离) if (oBdyType == BT_Rect || oBdyType == BT_Circle) { VecDouble vecBdyDiss; vecBdyDiss.clear(); int nCount = (oBdyType == BT_Rect ? 4 : 1); for (int i = 1; i <= nCount; i++) { QString sRealBdyName = getBdyRealNameOf(i, mapAnaParas); //sRealBdyName为map中边界距离key的真实内容 sKey = sRealBdyName; if (!sKey.isEmpty() && mapAnaParas.contains(sKey)) { vecBdyDiss << mapAnaParas[sKey].toDouble(); } else { Q_ASSERT (false);//TODO } } // 说明,对于BT_Rect,vecBdyDiss中存放的四个距离数值,依次为,上(ne)/下(se)/左(we)/右(ee) // 对于BT_Circle,vecBdyDiss中存放的是圆形半径r } ////////////////////////////////////////////////////////////////// return true; } QString nmSubWndUtils::getBdyRealNameOf(int xIndex, QMap& map) { QStringList list; list << "ne" << "se" << "we" << "ee" << "re"; int n = -1; for (int i = 0; i < list.count(); i++) { QString s = list[i]; if (map.find(s) != map.end()) { n++; if (n == xIndex - 1)//TODO -1,从1开始 { return s; } } } //m_sError = QString("Bdy name of 'x%1'' not found.").arg(xIndex); //zxLogRunF(m_sError); return ""; } bool nmSubWndUtils::nmCalAndFresh(iSubWnd* pSubWnd, \ const ZxMainWindow* pMainWnd) { return false; } bool nmSubWndUtils::saveRsts(iSubWnd* pSubWnd, \ QString sRstName, \ const ZxMainWindow* pMainWnd) { Q_ASSERT(nullptr != pSubWnd); if(pSubWnd == nullptr) { return false; } // 流动段分析窗体 if(pSubWnd->getWndID() == "3004") { // 转换为Fitting窗口 iSubWndFitting* pSubWndF = dynamic_cast(pSubWnd); if(pSubWndF == nullptr) { return false; } // 根据窗体指针,找到创建的对应的数据管理对象 nmDataAnalyzeManager*pDataManager = nmDataAnalyzeManager::findManagerByFitting(pSubWndF); // 如果不存在,则说明当前分析窗体没有做数值解,不需要做保存处理 if(pDataManager == nullptr) { return false; } // 如果存在,则对当前分析数据进行保存 if(!pDataManager->saveNmResult(sRstName, pSubWndF)) { return false; } } else if(pSubWnd->getWndID() == "5118") { return true; } else if(pSubWnd->getWndID() == "5114") { return true; } // TODO:Map窗口保存、网格窗口保存 return true; } bool nmSubWndUtils::loadRsts(iSubWnd* pSubWnd, \ QString sRstName, \ const ZxMainWindow* pMainWnd) { Q_ASSERT(nullptr != pSubWnd); if(pSubWnd == nullptr) { return false; } ZxMainWindow* pMainWnd1 = const_cast(pMainWnd); nmSubWndUtils* pUtilsInstance = nmSubWndUtils::getInstance(); if(nullptr != pMainWnd1) { ZxTabWidget* pTabWx = pMainWnd1->getCurTabWx(); if(nullptr != pTabWx) { if(pUtilsInstance->m_pTabWx == nullptr || pUtilsInstance->m_pTabWx != pTabWx) { pUtilsInstance->m_pTabWx = pTabWx; disconnect(pUtilsInstance->m_pTabWx, SIGNAL(currentChanged(int)), pUtilsInstance, SLOT(slotHandleTabChange(int))); connect(pUtilsInstance->m_pTabWx, SIGNAL(currentChanged(int)), pUtilsInstance, SLOT(slotHandleTabChange(int))); } } } // 处理流动段分析窗口数据 if(pSubWnd->getWndID() == "3004") { iSubWndFitting* pSubWndF = dynamic_cast(pSubWnd); if(pSubWndF == nullptr) { return false; } // 获取当前分析窗体Code ZxRstWnd* pRstWnd = pSubWndF->getRstUtilWnd(); if(pRstWnd == nullptr) { return false; } QString sRstUtilWndCode = pRstWnd->getCode(); ZxDataWell* pCurrentWell = pSubWndF->getDataWell(); if(pCurrentWell == nullptr) { return false; } // 获取该分析所在的目录 QString sDir = ZxBaseUtil::getWellDirOf(pCurrentWell->getName(), "Nm"); sDir += sRstName + "/" + sRstUtilWndCode; // 判断分析目录是否存在 bool bDirExists = nmDataAnalyzeManager::isDirExist(sDir); // 如果不存在,则说明没有保存数值解的参数 if(!bDirExists) { return false; } // 存在,说明保存了数值解的参数,需要解析文件里的数据到数据中心 // 动态创建数据中心类 nmDataAnalyzeManager* pDataManager = nmDataAnalyzeManager::getInstanceByFitting(pSubWndF); if(pDataManager == nullptr) { return false; } // 设置当前操作的是哪一个分析 nmDataAnalyzeManager::setCurrentFitting(pSubWndF); // 加载本地文件的数据到数据中心里的数据体里 pDataManager->loadNmResult(sDir); // 加载当前分析中的PVT数据 pDataManager->initPvtParaFromSubFit(); // 切换左侧参数视图 pSubWndF->swapAnaNmDocks(true); iDockBaseWx* pWxDockNm1 = pSubWndF->getNmDockWx(0); iDockBaseWx* pWxDockNm2 = pSubWndF->getNmDockWx(1); Q_ASSERT(nullptr != pWxDockNm1); Q_ASSERT(nullptr != pWxDockNm2); if(pWxDockNm1 == nullptr || pWxDockNm2 == nullptr) { return false; } if(pWxDockNm1->widget() != nullptr && pWxDockNm2->widget() != nullptr) { return true; //已经设定的话,则不再处理 } // 创建Map,暂时 nmSubWndMain* pSubWndMain = new nmSubWndMain(NULL, ""); ZxMainWindow* pMainWnd1 = const_cast(pMainWnd); pSubWndMain->setMainWindow(pMainWnd1); //pWxDockNm1->setWindowTitle(tr("Dock1's Title")); //pWxDockNm2->setWindowTitle(tr("Dock2's Title")); pWxDockNm1->setWindowTitle(tr("Generate numerical model")); //改变Title pWxDockNm2->setWindowTitle(tr("Parameters")); // 自定义窗体指针 nmWxNumericalDesign* pAnalWx = new nmWxNumericalDesign(); nmWxParameterProperty* pParaWx = new nmWxParameterProperty(); Q_ASSERT(nullptr != pAnalWx); Q_ASSERT(nullptr != pParaWx); // 建立求解调用连接 connect(pAnalWx, SIGNAL(sigGenerateClicked()), pSubWndMain, SLOT(onGenerateButtonClicked())); // 建立更新参数栏连接 connect(pAnalWx, SIGNAL(sigIncludeWells()), pParaWx, SLOT(onUpdate())); // 井图元更新连接 // connect(pAnalWx, SIGNAL(sigUpdateWellPlot(nmDataAnalyzeManager*)), // pSubWndMain, SLOT(slotUpdateWellPlotByDataManager(nmDataAnalyzeManager*))); //connect(pAnalWx, SIGNAL(sigIncludeWells()), // pParaWx, SLOT(onUpdate())); pWxDockNm1->setWidget(pAnalWx); pWxDockNm2->setWidget(pParaWx); // 判断是否保存了时间步数据 if(!pDataManager->isTimeStepDataEmpty()) { QString sErrorMessage; // 刷新场图 QWidget* p3DWidget = pSubWndF->getFitSubRstWxOf(FSRT_Nm3D, true, &sErrorMessage); // 创建 vtkWidget nmWxPostprocessingAnimationWidget* pVtkWidget = nullptr; pVtkWidget = new nmWxPostprocessingAnimationWidget(); if(p3DWidget == nullptr || pVtkWidget == nullptr) { delete pVtkWidget; return false; } // 先清理 // 获取当前布局 QLayout* p3DLayout = p3DWidget->layout(); if(p3DLayout) { // 移除布局中的所有控件 QLayoutItem* item; while((item = p3DLayout->takeAt(0))) { if(item->widget()) { // 删除控件 delete item->widget(); } delete item; // 删除布局项 } // 删除布局 delete p3DLayout; } // 确保布局被移除 p3DWidget->setLayout(nullptr); // 创建一个垂直布局管理器 QVBoxLayout* p3DnewLayout = new QVBoxLayout(p3DWidget); // 将现有的控件添加到布局中 p3DnewLayout->addWidget(pVtkWidget); // 设置 widget 的布局 p3DWidget->setLayout(p3DnewLayout); // 刷新结果参数 // 结果参数界面 QWidget* pRstWidget = pSubWndF->getFitSubRstWxOf(FSRT_NmRst, true, &sErrorMessage); if(pRstWidget == nullptr) { return false; } // 创建结果参数界面 nmWxResultParameters* pResultWidget = new nmWxResultParameters; // 先清理 // 获取当前布局 QLayout* pRstLayout = pRstWidget->layout(); if(pRstLayout) { // 移除布局中的所有控件 QLayoutItem* item; while((item = pRstLayout->takeAt(0))) { if(item->widget()) { // 删除控件 delete item->widget(); } delete item; // 删除布局项 } // 删除布局 delete pRstLayout; } // 确保布局被移除 pRstWidget->setLayout(nullptr); // 创建一个垂直布局管理器 QVBoxLayout* pRstnewLayout = new QVBoxLayout(pRstWidget); // 将现有的控件添加到布局中 pRstnewLayout->addWidget(pResultWidget); // 设置 widget 的布局 pRstWidget->setLayout(pRstnewLayout); } } //// 请根据需要确定,文件存储的路径 //QString sDir = ZxBaseUtil::getCurWellDirOf("Nm"); ////iSubWndFitting* pSubWndF = dynamic_cast(pSubWnd); ////Q_ASSERT(nullptr != pSubWndF); //QString sRstUtilWndCode = pSubWnd->getRstUtilWnd()->getCode(); //QByteArray ba = QByteArray();//这是你读取出来的内容 //ZxUiBase* pWx = nullptr; //your own widget //if (nullptr != pWx && !ba.isNull()) //{ // // 根据二进制内容更新窗体内容 // // 注意:loadFromByteArr是 iWxBase(PVT模块)中的接口,如果需要,请参考下面源码进行自行实现 // //pWx->loadFromByteArr(ba); //} // 如果需要把二进制内容更新至其它如double数组、map等存入,可以参照 ZxBaHelper 提供的接口 // 其它代码 return true; } // 如果需要加载某个窗体(继承自ZxUiBase,并且实现了序列化接口onSerialize/onDeserialize) // 则可以参照如下进行 #ifdef _SCAN_OLD_CODES_ bool iWxBase::saveAsByteArr(QByteArray& v) { QString sRoot = this->objectName() + "abc"; ZxXpfDoc xpf(sRoot); ZxSerializer ser(&xpf, true); onSerialize(&ser); QDataStream out(&v, QIODevice::WriteOnly); out.setVersion(QDataStream::Qt_4_8); if (xpf.save(out)) { return true; } else { return false; } return true; } bool iWxBase::loadFromByteArr(QByteArray& v) { QDataStream in(&v, QIODevice::ReadOnly); // quint32 nVer = ser->getDocDate(); // if (nVer > (quint32)(20180101)) // { // in.setVersion(QDataStream::Qt_4_8); // } // else { in.setVersion(QDataStream::Qt_4_8); } QString sRoot = this->objectName() + "abc"; ZxXpfDoc xpf(sRoot); if (!xpf.load(in)) { zxLogRunW(tr("Failed to load ByteArray")); return false; } ZxSerializer ser(&xpf, false); onDeserialize(&ser); return true; } #endif void nmSubWndUtils::slotHandleTabChange(int index) { // 找到索引对应的流动段分析窗体 if(m_pTabWx == nullptr) { return; } if(index >= 0 && index < m_pTabWx->count()) { iSubWnd* pSubWnd = dynamic_cast(m_pTabWx->widget(index)); if(pSubWnd == nullptr) { return; } // 切换的是流动段分析 if(pSubWnd->getWndID() == "3004") { iSubWndFitting* pSubWndF = dynamic_cast(pSubWnd); if(pSubWndF == nullptr) { return; } // 查找有没有对应的数据中心实例 nmDataAnalyzeManager* pDataManger = nmDataAnalyzeManager::findManagerByFitting(pSubWndF); if(pDataManger != nullptr && nmDataAnalyzeManager::getCurrentFitting() != pSubWndF) { // 有对应的实例,并且不是当前分析 nmDataAnalyzeManager::setCurrentFitting(pSubWndF); ZxMainWindow* pMainWnd = pSubWndF->getMainWindow(); Q_ASSERT(nullptr != pMainWnd); if(pMainWnd == nullptr) { return; } // 如果地图和网格窗体存在,则更新 QVector vecSubWnds = pMainWnd->getAllSubWndsOf(m_pTabWx); foreach(iSubWnd* pSub, vecSubWnds) { nmSubWndMain* pMap = dynamic_cast(pSub); if(nullptr != pMap) { // 更新地图相关信息 pMap->updateMapByDataManager(nmDataAnalyzeManager::getInstanceByFitting(pSubWndF)); } // TODO:网格更新 nmSubWndGrid* pSubWndGrid = dynamic_cast(pSub); if(nullptr != pSubWndGrid) { // 更新网格 disconnect(nmDataAnalyzeManager::getInstanceByFitting(pSubWndF), SIGNAL(dataChanged()), pSubWndGrid, SLOT(updateGrid())); connect(nmDataAnalyzeManager::getInstanceByFitting(pSubWndF), SIGNAL(dataChanged()), pSubWndGrid, SLOT(updateGrid()), Qt::QueuedConnection); // 手动更新 pSubWndGrid->updateGrid(); } } } } } }