修复打开map后关闭成果崩溃的问题

feature/UI-20260528
lvjunjie 6 days ago
parent 0cec2ca256
commit 2b721e6b8a

@ -12,6 +12,7 @@ class iSubWnd;
class iDockBaseWx;
class ZxTabWidget;
class QMdiSubWindow;
class ZxMdiSubWindow;
class QEvent;
class iSubWndFitting;
@ -136,6 +137,8 @@ public:
void connectMdiActivation(iSubWndFitting* pSubWndF);
// 单独关闭流动段分析页签时,移除仍引用其数据的画布图元
void detachFittingPlot(iSubWndFitting* pSubWndF);
// 关闭外层成果窗口时提前解除其Map图元对分析数据的引用
void detachMdiFittingPlots(ZxMdiSubWindow* pMdiChild);
// 因为边界是可以旋转的所以真实的顺序并非ee,se,we,ne根据索引传递查阅真实的比如 ee,se,we,ne
// xIndex 从1开始如果矩形则分别传入1,2,3,4 如果是圆形则传入1
@ -148,6 +151,6 @@ public:
// destroyed信号异步处理时通过QObject地址取回析构前保存的分析窗口key
QMap<QObject*, iSubWndFitting*> m_mapFittingKeys;
// 外层成果窗口关闭时,其画布由自身析构流程释放,不能再次主动遍历
// 外层成果窗口关闭时,其画布已在MDI Close阶段清理后续子窗口Close不再重复处理
QSet<QObject*> m_closingMdiChildren;
};

@ -131,6 +131,15 @@ nmSubWndMain::nmSubWndMain(QWidget *parent, QString sExt) :
nmSubWndMain::~nmSubWndMain()
{
if(m_pWxPlot != nullptr) {
// Map窗口析构时解除DataManager中保存的Plot引用避免后续访问已释放画布。
foreach(nmDataAnalyzeManager* pManager, nmDataAnalyzeManager::s_mapDataAnalManager.values()) {
if(pManager != nullptr && pManager->getPlot() == m_pWxPlot) {
pManager->setPlot(nullptr);
}
}
}
#ifdef QT_DEBUG
// 坚持谁创建谁析构原则,删除(首先需要去除绑定)
@ -2423,6 +2432,7 @@ void nmSubWndMain::updateMapByDataManager(nmDataAnalyzeManager* pDataManager)
return;
}
// 一个Map同一时间只展示一个分析的数据切换前先解除其他DataManager对当前Plot的绑定。
foreach(nmDataAnalyzeManager* pManager, nmDataAnalyzeManager::s_mapDataAnalManager.values()) {
if(pManager != nullptr && pManager != pDataManager && pManager->getPlot() == m_pWxPlot) {
pManager->setPlot(nullptr);

@ -40,6 +40,7 @@ void nmSubWndSubWxsAnalyzeController::updateWindowsForCurrentAnalyze(ZxMainWindo
ZxTabWidget* pTabWx = pMainWindow->getCurTabWx();
QVector<iSubWnd*> vecSubWnds = pMainWindow->getAllSubWndsOf(pTabWx);
// 本轮刷新只使用目标分析对应的数据中心,地图和网格保持同一个实例。
nmDataAnalyzeManager* pManager = nmDataAnalyzeManager::getInstanceByFitting(pCurSubWndF);
foreach (iSubWnd* pSub, vecSubWnds) {
nmSubWndMain* pMap = dynamic_cast<nmSubWndMain*>(pSub);

@ -1,6 +1,5 @@
#include "zxLogInstance.h"
#include "iRibbonXmlCmd.h"
#include <QDebug>
#include <QEvent>
#include <QMdiArea>
#include <QMdiSubWindow>
@ -1083,7 +1082,7 @@ void nmSubWndUtils::slotHandleTabChange(int index)
if(nullptr != pMap) {
// 更新地图相关信息
pMap->updateMapByDataManager(nmDataAnalyzeManager::getInstanceByFitting(pSubWndF));
pMap->updateMapByDataManager(pDataManger);
}
// TODO网格更新
@ -1091,8 +1090,8 @@ void nmSubWndUtils::slotHandleTabChange(int index)
if(nullptr != pSubWndGrid) {
// 更新网格
disconnect(nmDataAnalyzeManager::getInstanceByFitting(pSubWndF), SIGNAL(dataChanged()), pSubWndGrid, SLOT(updateGrid()));
connect(nmDataAnalyzeManager::getInstanceByFitting(pSubWndF), SIGNAL(dataChanged()), pSubWndGrid, SLOT(updateGrid()), Qt::QueuedConnection);
disconnect(pDataManger, SIGNAL(dataChanged()), pSubWndGrid, SLOT(updateGrid()));
connect(pDataManger, SIGNAL(dataChanged()), pSubWndGrid, SLOT(updateGrid()), Qt::QueuedConnection);
// 手动更新
pSubWndGrid->updateGrid();
}
@ -1184,12 +1183,40 @@ void nmSubWndUtils::detachFittingPlot(iSubWndFitting* pSubWndF)
if(nmDataAnalyzeManager::getCurrentFitting() != pSubWndF) {
nmDataAnalyzeManager* pCurManager = nmDataAnalyzeManager::getCurrentInstance();
if(pCurManager != nullptr) {
// 关闭的不是当前分析时清掉待关闭分析图元后恢复当前分析的Map显示。
pCurManager->setPlot(pPlot);
pPlot->setPlotsByDataManger(pCurManager);
}
}
}
// 外层成果窗口关闭时先清理仍绑定到Map上的图元
void nmSubWndUtils::detachMdiFittingPlots(ZxMdiSubWindow* pMdiChild)
{
if(pMdiChild == nullptr || m_pMainWnd == nullptr) {
return;
}
ZxTabWidget* pTabWx = m_pMainWnd->getTabWxOf(pMdiChild);
if(pTabWx == nullptr) {
return;
}
QVector<iSubWnd*> vecSubWnds = m_pMainWnd->getAllSubWndsOf(pTabWx, "3004", true);
// 同一个成果内可能有多个分析只清理仍占用Map Plot的DataManager。
foreach(iSubWnd* pSubWnd, vecSubWnds) {
iSubWndFitting* pSubWndF = dynamic_cast<iSubWndFitting*>(pSubWnd);
nmDataAnalyzeManager* pDataManager = nmDataAnalyzeManager::findManagerByFitting(pSubWndF);
if(pDataManager == nullptr || pDataManager->getPlot() == nullptr) {
continue;
}
nmGuiPlot* pPlot = pDataManager->getPlot();
pPlot->deleteAllPlotObjs();
pDataManager->setPlot(nullptr);
}
}
// 流动段分析窗口销毁后,释放对应的数据管理器
void nmSubWndUtils::slotHandleFittingDestroyed(QObject* pObject)
{
@ -1203,6 +1230,13 @@ void nmSubWndUtils::slotHandleMdiClosing(bool& bAllowClose)
{
if(!bAllowClose) {
m_closingMdiChildren.remove(sender());
return;
}
// 用户确认关闭成果窗口后再清理Map避免取消关闭时误清当前显示。
ZxMdiSubWindow* pMdiChild = qobject_cast<ZxMdiSubWindow*>(sender());
if(pMdiChild != nullptr) {
detachMdiFittingPlots(pMdiChild);
}
}

Loading…
Cancel
Save