From 6e34d44f0b7cd7e2c4458660cd381e755cea3697 Mon Sep 17 00:00:00 2001 From: lvjunjie Date: Wed, 5 Aug 2026 16:11:30 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=89=B9=E9=87=8F=E9=80=89?= =?UTF-8?q?=E4=BA=95=E5=8A=A0=E8=BD=BD=E6=80=A7=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 使用集合计算井图元差集,并在批量增删期间合并 Map 重绘。 合并井列表变更触发的参数面板刷新,避免逐井完整重建。 --- Include/nmNum/nmSubWxs/nmWxParaPropertyPebi.h | 10 +++++++ Src/nmNum/nmSubWnd/nmSubWndMain.cpp | 26 ++++++++++++++--- Src/nmNum/nmSubWxs/nmWxParaPropertyPebi.cpp | 28 ++++++++++++++++++- 3 files changed, 59 insertions(+), 5 deletions(-) diff --git a/Include/nmNum/nmSubWxs/nmWxParaPropertyPebi.h b/Include/nmNum/nmSubWxs/nmWxParaPropertyPebi.h index 5488a07..d4d6938 100644 --- a/Include/nmNum/nmSubWxs/nmWxParaPropertyPebi.h +++ b/Include/nmNum/nmSubWxs/nmWxParaPropertyPebi.h @@ -5,6 +5,7 @@ class nmGridRowUtils; class nmDataAnalyzeManager; +class QTimer; /// @brief PEBI求解器专用的参数输入/编辑属性对话框窗体 /// @note 与 nmWxParaProperty 结构一致,区别在于内部使用 nmGridRowUtils(NM子类) @@ -80,6 +81,8 @@ public slots: void slotWellRemoved(QString wellCode, QString wellName); /// @brief 几何对象新增、删除或改名后重建参数面板 void slotGeometryListChanged(); + /// @brief 合并同一轮事件中的多次井列表变化,只重建一次参数面板 + void slotDeferredWellListRebuild(); protected: @@ -100,6 +103,13 @@ protected: // 数据管理器引用(用于全量重建面板时获取井和几何对象列表) nmDataAnalyzeManager* m_pDataManager; + // 批量增删井时合并参数面板刷新 + QTimer* m_pWellListRebuildTimer; + +private: + + void scheduleWellListRebuild(); + signals: /// @brief 参数值变更信号(由 slotParaCtrlValueChanged 转发) diff --git a/Src/nmNum/nmSubWnd/nmSubWndMain.cpp b/Src/nmNum/nmSubWnd/nmSubWndMain.cpp index f207478..b33b517 100644 --- a/Src/nmNum/nmSubWnd/nmSubWndMain.cpp +++ b/Src/nmNum/nmSubWnd/nmSubWndMain.cpp @@ -64,6 +64,7 @@ #include "iAnalRun.h" #include +#include #include "nmSingalCenter.h" @@ -986,8 +987,18 @@ void nmSubWndMain::updateSelectedWells(QList wellObjList) } } - // 当前在画布上的所有 ZxDataWell* 数据列表 (Key Set) + // 用集合保存当前井和选中井,避免井数增加后反复调用 QList::contains 造成平方级查找。 QList pWellPlotDataList = pWellDataToPlotMap.keys(); + QSet pWellPlotDataSet; + for(int i = 0; i < pWellPlotDataList.count(); ++i) { + pWellPlotDataSet.insert(pWellPlotDataList[i]); + } + QSet selectedWellDataSet; + for(int i = 0; i < wellObjList.count(); ++i) { + if(wellObjList[i] != nullptr) { + selectedWellDataSet.insert(wellObjList[i]); + } + } // setp 2,找出需要 REMOVE (删除) 的图元 QVector vDeleteWellPlotList; @@ -996,7 +1007,7 @@ void nmSubWndMain::updateSelectedWells(QList wellObjList) for(int i = 0; i < pWellPlotDataList.count(); ++i) { ZxDataWell *pWellDataOnPlot = pWellPlotDataList[i]; // 如果该井数据不在用户选中的列表 wellObjList 中,则需要删除 - if (!wellObjList.contains(pWellDataOnPlot)) { + if (!selectedWellDataSet.contains(pWellDataOnPlot)) { // 从 Map 中获取对应的图元对象 vDeleteWellPlotList.append(pWellDataToPlotMap.value(pWellDataOnPlot)); } @@ -1009,12 +1020,16 @@ void nmSubWndMain::updateSelectedWells(QList wellObjList) for(int i = 0; i < wellObjList.count(); ++i) { ZxDataWell *pWellDataSelected = wellObjList[i]; // 确保井数据有效 - if (pWellDataSelected && !pWellPlotDataList.contains(pWellDataSelected)) { + if (pWellDataSelected && !pWellPlotDataSet.contains(pWellDataSelected)) { // 如果该井数据不在当前画布上的数据列表中,则需要添加 vAddWellPlotList.append(pWellDataSelected); } } + // 单井增删过程中会多次请求重绘;批量阶段先暂停,全部处理完成后再统一刷新。 + const bool updatesEnabled = m_pWxPlot->updatesEnabled(); + m_pWxPlot->setUpdatesEnabled(false); + // setp 4,执行删除操作 for(int i = 0; i < vDeleteWellPlotList.count(); ++i) { nmObjPointWell* pWellPlot = vDeleteWellPlotList[i]; @@ -1056,7 +1071,10 @@ void nmSubWndMain::updateSelectedWells(QList wellObjList) // 添加完毕后,重新渲染 - m_pWxPlot->update(); + m_pWxPlot->setUpdatesEnabled(updatesEnabled); + if(updatesEnabled) { + m_pWxPlot->update(); + } } // 地质图导入 diff --git a/Src/nmNum/nmSubWxs/nmWxParaPropertyPebi.cpp b/Src/nmNum/nmSubWxs/nmWxParaPropertyPebi.cpp index 7eb051f..f687416 100644 --- a/Src/nmNum/nmSubWxs/nmWxParaPropertyPebi.cpp +++ b/Src/nmNum/nmSubWxs/nmWxParaPropertyPebi.cpp @@ -23,6 +23,7 @@ #include #include +#include #include "nmWxParaPropertyPebi.h" @@ -195,6 +196,11 @@ nmWxParaPropertyPebi::nmWxParaPropertyPebi(QWidget* parent) : m_pGridItemUtils = nullptr; m_pHelpBox = nullptr; m_pDataManager = nullptr; + // 0ms 单次定时器用于合并同一轮事件中的多次井增删通知。 + m_pWellListRebuildTimer = new QTimer(this); + m_pWellListRebuildTimer->setSingleShot(true); + connect(m_pWellListRebuildTimer, SIGNAL(timeout()), + this, SLOT(slotDeferredWellListRebuild())); setWindowTitle(tr("Numerical para property")); } @@ -376,6 +382,12 @@ void nmWxParaPropertyPebi::slotParaCtrlValueChanged(QString sPara, QVariant o) void nmWxParaPropertyPebi::rebuildAllParas() { + // 已有显式全量重建时,取消尚未执行的延迟刷新,避免重复重建面板。 + if (m_pWellListRebuildTimer != nullptr && m_pWellListRebuildTimer->isActive()) + { + m_pWellListRebuildTimer->stop(); + } + if (m_pMainLayout == nullptr || m_pDataManager == nullptr) return; @@ -779,13 +791,27 @@ void nmWxParaPropertyPebi::slotWellAdded(QString wellCode, QString wellName, QSt Q_UNUSED(wellCode); Q_UNUSED(wellName); Q_UNUSED(paras); - rebuildAllParas(); + scheduleWellListRebuild(); } void nmWxParaPropertyPebi::slotWellRemoved(QString wellCode, QString wellName) { Q_UNUSED(wellCode); Q_UNUSED(wellName); + scheduleWellListRebuild(); +} + +void nmWxParaPropertyPebi::scheduleWellListRebuild() +{ + if (m_pWellListRebuildTimer != nullptr) + { + // 批量循环内重复 start 会重置同一个单次定时器,返回事件循环后只触发一次。 + m_pWellListRebuildTimer->start(0); + } +} + +void nmWxParaPropertyPebi::slotDeferredWellListRebuild() +{ rebuildAllParas(); }