mirror of
				https://github.com/qgis/QGIS.git
				synced 2025-11-03 00:14:12 -05:00 
			
		
		
		
	Cleanup iface signal connections when unloading processing
plugin Fixes #53455
This commit is contained in:
		
							parent
							
								
									371f51eabf
								
							
						
					
					
						commit
						30acad6819
					
				@ -22,6 +22,7 @@ __copyright__ = '(C) 2012, Victor Olaya'
 | 
				
			|||||||
import shutil
 | 
					import shutil
 | 
				
			||||||
import os
 | 
					import os
 | 
				
			||||||
import sys
 | 
					import sys
 | 
				
			||||||
 | 
					from typing import List
 | 
				
			||||||
from functools import partial
 | 
					from functools import partial
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from qgis.core import (QgsApplication,
 | 
					from qgis.core import (QgsApplication,
 | 
				
			||||||
@ -38,9 +39,25 @@ from qgis.gui import (QgsGui,
 | 
				
			|||||||
                      QgsOptionsWidgetFactory,
 | 
					                      QgsOptionsWidgetFactory,
 | 
				
			||||||
                      QgsCustomDropHandler,
 | 
					                      QgsCustomDropHandler,
 | 
				
			||||||
                      QgsProcessingHistoryDialog)
 | 
					                      QgsProcessingHistoryDialog)
 | 
				
			||||||
from qgis.PyQt.QtCore import QObject, Qt, QItemSelectionModel, QCoreApplication, QDir, QFileInfo, pyqtSlot
 | 
					from qgis.PyQt.QtCore import (
 | 
				
			||||||
from qgis.PyQt.QtWidgets import QWidget, QMenu, QAction
 | 
					    QObject,
 | 
				
			||||||
from qgis.PyQt.QtGui import QIcon, QKeySequence
 | 
					    Qt,
 | 
				
			||||||
 | 
					    QItemSelectionModel,
 | 
				
			||||||
 | 
					    QCoreApplication,
 | 
				
			||||||
 | 
					    QDir,
 | 
				
			||||||
 | 
					    QFileInfo,
 | 
				
			||||||
 | 
					    pyqtSlot,
 | 
				
			||||||
 | 
					    QMetaObject
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					from qgis.PyQt.QtWidgets import (
 | 
				
			||||||
 | 
					    QWidget,
 | 
				
			||||||
 | 
					    QMenu,
 | 
				
			||||||
 | 
					    QAction
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					from qgis.PyQt.QtGui import (
 | 
				
			||||||
 | 
					    QIcon,
 | 
				
			||||||
 | 
					    QKeySequence
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
from qgis.utils import iface
 | 
					from qgis.utils import iface
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from processing.core.Processing import Processing
 | 
					from processing.core.Processing import Processing
 | 
				
			||||||
@ -177,6 +194,7 @@ class ProcessingPlugin(QObject):
 | 
				
			|||||||
        self.locator_filter = None
 | 
					        self.locator_filter = None
 | 
				
			||||||
        self.edit_features_locator_filter = None
 | 
					        self.edit_features_locator_filter = None
 | 
				
			||||||
        self.initialized = False
 | 
					        self.initialized = False
 | 
				
			||||||
 | 
					        self._gui_connections: List[QMetaObject.Connection] = []
 | 
				
			||||||
        self.initProcessing()
 | 
					        self.initProcessing()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def initProcessing(self):
 | 
					    def initProcessing(self):
 | 
				
			||||||
@ -203,7 +221,9 @@ class ProcessingPlugin(QObject):
 | 
				
			|||||||
        self.locator_filter = AlgorithmLocatorFilter()
 | 
					        self.locator_filter = AlgorithmLocatorFilter()
 | 
				
			||||||
        iface.registerLocatorFilter(self.locator_filter)
 | 
					        iface.registerLocatorFilter(self.locator_filter)
 | 
				
			||||||
        # Invalidate the locator filter for in-place when active layer changes
 | 
					        # Invalidate the locator filter for in-place when active layer changes
 | 
				
			||||||
        iface.currentLayerChanged.connect(lambda _: self.iface.invalidateLocatorResults())
 | 
					        self._gui_connections.append(
 | 
				
			||||||
 | 
					            iface.currentLayerChanged.connect(lambda _: self.iface.invalidateLocatorResults())
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
        self.edit_features_locator_filter = InPlaceAlgorithmLocatorFilter()
 | 
					        self.edit_features_locator_filter = InPlaceAlgorithmLocatorFilter()
 | 
				
			||||||
        iface.registerLocatorFilter(self.edit_features_locator_filter)
 | 
					        iface.registerLocatorFilter(self.edit_features_locator_filter)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -303,9 +323,19 @@ class ProcessingPlugin(QObject):
 | 
				
			|||||||
        createButtons()
 | 
					        createButtons()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # In-place editing button state sync
 | 
					        # In-place editing button state sync
 | 
				
			||||||
        self.iface.currentLayerChanged.connect(self.sync_in_place_button_state)
 | 
					
 | 
				
			||||||
        self.iface.mapCanvas().selectionChanged.connect(self.sync_in_place_button_state)
 | 
					        # we need to explicitly store and disconnect these connections
 | 
				
			||||||
        self.iface.actionToggleEditing().triggered.connect(partial(self.sync_in_place_button_state, None))
 | 
					        # on plugin unload -- they aren't cleaned up automatically (see
 | 
				
			||||||
 | 
					        # https://github.com/qgis/QGIS/issues/53455)
 | 
				
			||||||
 | 
					        self._gui_connections.append(
 | 
				
			||||||
 | 
					            self.iface.currentLayerChanged.connect(self.sync_in_place_button_state)
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        self._gui_connections.append(
 | 
				
			||||||
 | 
					            self.iface.mapCanvas().selectionChanged.connect(self.sync_in_place_button_state)
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        self._gui_connections.append(
 | 
				
			||||||
 | 
					            self.iface.actionToggleEditing().triggered.connect(partial(self.sync_in_place_button_state, None))
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
        self.sync_in_place_button_state()
 | 
					        self.sync_in_place_button_state()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Sync project models
 | 
					        # Sync project models
 | 
				
			||||||
@ -314,7 +344,9 @@ class ProcessingPlugin(QObject):
 | 
				
			|||||||
        self.projectMenuSeparator = None
 | 
					        self.projectMenuSeparator = None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.projectProvider = QgsApplication.instance().processingRegistry().providerById("project")
 | 
					        self.projectProvider = QgsApplication.instance().processingRegistry().providerById("project")
 | 
				
			||||||
        self.projectProvider.algorithmsLoaded.connect(self.updateProjectModelMenu)
 | 
					        self._gui_connections.append(
 | 
				
			||||||
 | 
					            self.projectProvider.algorithmsLoaded.connect(self.updateProjectModelMenu)
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def updateProjectModelMenu(self):
 | 
					    def updateProjectModelMenu(self):
 | 
				
			||||||
        """Add projects models to menu"""
 | 
					        """Add projects models to menu"""
 | 
				
			||||||
@ -433,6 +465,9 @@ class ProcessingPlugin(QObject):
 | 
				
			|||||||
        self.iface.showOptionsDialog(self.iface.mainWindow(), currentPage='processingOptions')
 | 
					        self.iface.showOptionsDialog(self.iface.mainWindow(), currentPage='processingOptions')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def unload(self):
 | 
					    def unload(self):
 | 
				
			||||||
 | 
					        for connection in self._gui_connections:
 | 
				
			||||||
 | 
					            self.disconnect(connection)
 | 
				
			||||||
 | 
					        self._gui_connections = []
 | 
				
			||||||
        self.toolbox.setVisible(False)
 | 
					        self.toolbox.setVisible(False)
 | 
				
			||||||
        self.iface.removeDockWidget(self.toolbox)
 | 
					        self.iface.removeDockWidget(self.toolbox)
 | 
				
			||||||
        self.iface.attributesToolBar().removeAction(self.toolboxAction)
 | 
					        self.iface.attributesToolBar().removeAction(self.toolboxAction)
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user