From 7f4f677ce14670130a92f3009e360af95a0b0658 Mon Sep 17 00:00:00 2001 From: Martin Date: Sun, 21 Feb 2021 06:49:07 -0800 Subject: [PATCH 1/3] lambdas which reference self prevent GC --- pyqtgraph/graphicsItems/GradientEditorItem.py | 19 +++++--- pyqtgraph/graphicsItems/LinearRegionItem.py | 12 +++-- pyqtgraph/graphicsItems/ROI.py | 7 ++- pyqtgraph/parametertree/Parameter.py | 45 +++++++++++++++---- 4 files changed, 64 insertions(+), 19 deletions(-) diff --git a/pyqtgraph/graphicsItems/GradientEditorItem.py b/pyqtgraph/graphicsItems/GradientEditorItem.py index 8c8e5171..63e25d07 100644 --- a/pyqtgraph/graphicsItems/GradientEditorItem.py +++ b/pyqtgraph/graphicsItems/GradientEditorItem.py @@ -446,10 +446,10 @@ class GradientEditorItem(TickSliderItem): self.rgbAction = QtGui.QAction(translate("GradiantEditorItem", 'RGB'), self) self.rgbAction.setCheckable(True) - self.rgbAction.triggered.connect(lambda: self.setColorMode('rgb')) + self.rgbAction.triggered.connect(self.setColorModeToRGB) self.hsvAction = QtGui.QAction(translate("GradiantEditorItem", 'HSV'), self) self.hsvAction.setCheckable(True) - self.hsvAction.triggered.connect(lambda: self.setColorMode('hsv')) + self.hsvAction.triggered.connect(self.setColorModeToHSV) self.menu = QtGui.QMenu() @@ -493,7 +493,7 @@ class GradientEditorItem(TickSliderItem): self.updateGradient() self.linkedGradients = {} - self.sigTicksChanged.connect(lambda *args, **kwargs: self.updateGradient()) + self.sigTicksChanged.connect(self.updateGradientIgnoreArgs) self.sigTicksChangeFinished.connect(self.sigGradientChangeFinished.emit) def showTicks(self, show=True): @@ -566,7 +566,13 @@ class GradientEditorItem(TickSliderItem): self.sigTicksChanged.emit(self) self.sigGradientChangeFinished.emit(self) - + + def setColorModeToRGB(self): + self.setColorMode("rgb") + + def setColorModeToHSV(self): + self.setColorMode("hsv") + def colorMap(self): """Return a ColorMap object representing the current state of the editor.""" if self.colorMode == 'hsv': @@ -584,7 +590,10 @@ class GradientEditorItem(TickSliderItem): self.gradient = self.getGradient() self.gradRect.setBrush(QtGui.QBrush(self.gradient)) self.sigGradientChanged.emit(self) - + + def updateGradientIgnoreArgs(self, *args, **kwargs): + self.updateGradient() + def setLength(self, newLen): #private (but maybe public) TickSliderItem.setLength(self, newLen) diff --git a/pyqtgraph/graphicsItems/LinearRegionItem.py b/pyqtgraph/graphicsItems/LinearRegionItem.py index 1b818461..3bcb48dd 100644 --- a/pyqtgraph/graphicsItems/LinearRegionItem.py +++ b/pyqtgraph/graphicsItems/LinearRegionItem.py @@ -110,8 +110,8 @@ class LinearRegionItem(GraphicsObject): for l in self.lines: l.setParentItem(self) l.sigPositionChangeFinished.connect(self.lineMoveFinished) - self.lines[0].sigPositionChanged.connect(lambda: self.lineMoved(0)) - self.lines[1].sigPositionChanged.connect(lambda: self.lineMoved(1)) + self.lines[0].sigPositionChanged.connect(self.line0Moved) + self.lines[1].sigPositionChanged.connect(self.line1Moved) if brush is None: brush = QtGui.QBrush(QtGui.QColor(0, 0, 255, 50)) @@ -241,7 +241,13 @@ class LinearRegionItem(GraphicsObject): self.prepareGeometryChange() self.sigRegionChanged.emit(self) - + + def line0Moved(self): + self.lineMoved(0) + + def line1Moved(self): + self.lineMoved(1) + def lineMoveFinished(self): self.sigRegionChangeFinished.emit(self) diff --git a/pyqtgraph/graphicsItems/ROI.py b/pyqtgraph/graphicsItems/ROI.py index efd0bdc2..2c6584c3 100644 --- a/pyqtgraph/graphicsItems/ROI.py +++ b/pyqtgraph/graphicsItems/ROI.py @@ -785,8 +785,11 @@ class ROI(GraphicsObject): def removeClicked(self): ## Send remove event only after we have exited the menu event handler - QtCore.QTimer.singleShot(0, lambda: self.sigRemoveRequested.emit(self)) - + QtCore.QTimer.singleShot(0, self.emitRemoveRequest) + + def emitRemoveRequest(self): + self.sigRemoveRequested.emit(self) + def mouseDragEvent(self, ev): self.mouseDragHandler.mouseDragEvent(ev) diff --git a/pyqtgraph/parametertree/Parameter.py b/pyqtgraph/parametertree/Parameter.py index ef4f0324..581d15cb 100644 --- a/pyqtgraph/parametertree/Parameter.py +++ b/pyqtgraph/parametertree/Parameter.py @@ -203,15 +203,15 @@ class Parameter(QtCore.QObject): self.opts['default'] = None ## Connect all state changed signals to the general sigStateChanged - self.sigValueChanged.connect(lambda param, data: self.emitStateChanged('value', data)) - self.sigChildAdded.connect(lambda param, *data: self.emitStateChanged('childAdded', data)) - self.sigChildRemoved.connect(lambda param, data: self.emitStateChanged('childRemoved', data)) - self.sigParentChanged.connect(lambda param, data: self.emitStateChanged('parent', data)) - self.sigLimitsChanged.connect(lambda param, data: self.emitStateChanged('limits', data)) - self.sigDefaultChanged.connect(lambda param, data: self.emitStateChanged('default', data)) - self.sigNameChanged.connect(lambda param, data: self.emitStateChanged('name', data)) - self.sigOptionsChanged.connect(lambda param, data: self.emitStateChanged('options', data)) - self.sigContextMenu.connect(lambda param, data: self.emitStateChanged('contextMenu', data)) + self.sigValueChanged.connect(self.emitValueChanged) + self.sigChildAdded.connect(self.emitChildAddedChanged) + self.sigChildRemoved.connect(self.emitChildRemovedChanged) + self.sigParentChanged.connect(self.emitParentChanged) + self.sigLimitsChanged.connect(self.emitLimitsChanged) + self.sigDefaultChanged.connect(self.emitDefaultChanged) + self.sigNameChanged.connect(self.emitNameChanged) + self.sigOptionsChanged.connect(self.emitOptionsChanged) + self.sigContextMenu.connect(self.emitContextMenuChanged) #self.watchParam(self) ## emit treechange signals if our own state changes @@ -511,6 +511,33 @@ class Parameter(QtCore.QObject): self.treeStateChanges.append((self, changeDesc, data)) self.emitTreeChanges() + def emitValueChanged(self, param, data): + self.emitStateChanged("value", data) + + def emitChildAddedChanged(self, param, *data): + self.emitStateChanged("childAdded", data) + + def emitchildRemovedChanged(self, param, data): + self.emitStateChanged("childRemoved", data) + + def emitParentChanged(self, param, data): + self.emitStateChanged("parent", data) + + def emitLimitsChanged(self, param, data): + self.emitStateChanged("limits", data) + + def emitDefaultChanged(self, param, data): + self.emitStateChanged("default", data) + + def emitNameChanged(self, param, data): + self.emitStateChanged("name", data) + + def emitOptionsChanged(self, param, data): + self.emitStateChanged("options", data) + + def emitContextMenuChanged(self, param, data): + self.emitStateChanged("contextMenu", data) + def makeTreeItem(self, depth): """ Return a TreeWidgetItem suitable for displaying/controlling the content of From 68fa95686b77d3edf75dda6be635b1f970f67942 Mon Sep 17 00:00:00 2001 From: Martin Date: Sun, 21 Feb 2021 07:05:24 -0800 Subject: [PATCH 2/3] fix typo --- pyqtgraph/parametertree/Parameter.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyqtgraph/parametertree/Parameter.py b/pyqtgraph/parametertree/Parameter.py index 581d15cb..bf9f156a 100644 --- a/pyqtgraph/parametertree/Parameter.py +++ b/pyqtgraph/parametertree/Parameter.py @@ -517,7 +517,7 @@ class Parameter(QtCore.QObject): def emitChildAddedChanged(self, param, *data): self.emitStateChanged("childAdded", data) - def emitchildRemovedChanged(self, param, data): + def emitChildRemovedChanged(self, param, data): self.emitStateChanged("childRemoved", data) def emitParentChanged(self, param, data): From af82858bc854a760998ee6cba9c04de7bf955b15 Mon Sep 17 00:00:00 2001 From: Martin Date: Sun, 21 Feb 2021 22:29:56 -0800 Subject: [PATCH 3/3] make these tiny methods with little excuse to exist private --- pyqtgraph/graphicsItems/GradientEditorItem.py | 12 +++---- pyqtgraph/graphicsItems/LinearRegionItem.py | 8 ++--- pyqtgraph/graphicsItems/ROI.py | 4 +-- pyqtgraph/parametertree/Parameter.py | 36 +++++++++---------- 4 files changed, 30 insertions(+), 30 deletions(-) diff --git a/pyqtgraph/graphicsItems/GradientEditorItem.py b/pyqtgraph/graphicsItems/GradientEditorItem.py index 63e25d07..50d38a0e 100644 --- a/pyqtgraph/graphicsItems/GradientEditorItem.py +++ b/pyqtgraph/graphicsItems/GradientEditorItem.py @@ -446,10 +446,10 @@ class GradientEditorItem(TickSliderItem): self.rgbAction = QtGui.QAction(translate("GradiantEditorItem", 'RGB'), self) self.rgbAction.setCheckable(True) - self.rgbAction.triggered.connect(self.setColorModeToRGB) + self.rgbAction.triggered.connect(self._setColorModeToRGB) self.hsvAction = QtGui.QAction(translate("GradiantEditorItem", 'HSV'), self) self.hsvAction.setCheckable(True) - self.hsvAction.triggered.connect(self.setColorModeToHSV) + self.hsvAction.triggered.connect(self._setColorModeToHSV) self.menu = QtGui.QMenu() @@ -493,7 +493,7 @@ class GradientEditorItem(TickSliderItem): self.updateGradient() self.linkedGradients = {} - self.sigTicksChanged.connect(self.updateGradientIgnoreArgs) + self.sigTicksChanged.connect(self._updateGradientIgnoreArgs) self.sigTicksChangeFinished.connect(self.sigGradientChangeFinished.emit) def showTicks(self, show=True): @@ -567,10 +567,10 @@ class GradientEditorItem(TickSliderItem): self.sigTicksChanged.emit(self) self.sigGradientChangeFinished.emit(self) - def setColorModeToRGB(self): + def _setColorModeToRGB(self): self.setColorMode("rgb") - def setColorModeToHSV(self): + def _setColorModeToHSV(self): self.setColorMode("hsv") def colorMap(self): @@ -591,7 +591,7 @@ class GradientEditorItem(TickSliderItem): self.gradRect.setBrush(QtGui.QBrush(self.gradient)) self.sigGradientChanged.emit(self) - def updateGradientIgnoreArgs(self, *args, **kwargs): + def _updateGradientIgnoreArgs(self, *args, **kwargs): self.updateGradient() def setLength(self, newLen): diff --git a/pyqtgraph/graphicsItems/LinearRegionItem.py b/pyqtgraph/graphicsItems/LinearRegionItem.py index 3bcb48dd..6f888613 100644 --- a/pyqtgraph/graphicsItems/LinearRegionItem.py +++ b/pyqtgraph/graphicsItems/LinearRegionItem.py @@ -110,8 +110,8 @@ class LinearRegionItem(GraphicsObject): for l in self.lines: l.setParentItem(self) l.sigPositionChangeFinished.connect(self.lineMoveFinished) - self.lines[0].sigPositionChanged.connect(self.line0Moved) - self.lines[1].sigPositionChanged.connect(self.line1Moved) + self.lines[0].sigPositionChanged.connect(self._line0Moved) + self.lines[1].sigPositionChanged.connect(self._line1Moved) if brush is None: brush = QtGui.QBrush(QtGui.QColor(0, 0, 255, 50)) @@ -242,10 +242,10 @@ class LinearRegionItem(GraphicsObject): self.prepareGeometryChange() self.sigRegionChanged.emit(self) - def line0Moved(self): + def _line0Moved(self): self.lineMoved(0) - def line1Moved(self): + def _line1Moved(self): self.lineMoved(1) def lineMoveFinished(self): diff --git a/pyqtgraph/graphicsItems/ROI.py b/pyqtgraph/graphicsItems/ROI.py index 2c6584c3..99b2882d 100644 --- a/pyqtgraph/graphicsItems/ROI.py +++ b/pyqtgraph/graphicsItems/ROI.py @@ -785,9 +785,9 @@ class ROI(GraphicsObject): def removeClicked(self): ## Send remove event only after we have exited the menu event handler - QtCore.QTimer.singleShot(0, self.emitRemoveRequest) + QtCore.QTimer.singleShot(0, self._emitRemoveRequest) - def emitRemoveRequest(self): + def _emitRemoveRequest(self): self.sigRemoveRequested.emit(self) def mouseDragEvent(self, ev): diff --git a/pyqtgraph/parametertree/Parameter.py b/pyqtgraph/parametertree/Parameter.py index bf9f156a..e2225047 100644 --- a/pyqtgraph/parametertree/Parameter.py +++ b/pyqtgraph/parametertree/Parameter.py @@ -203,15 +203,15 @@ class Parameter(QtCore.QObject): self.opts['default'] = None ## Connect all state changed signals to the general sigStateChanged - self.sigValueChanged.connect(self.emitValueChanged) - self.sigChildAdded.connect(self.emitChildAddedChanged) - self.sigChildRemoved.connect(self.emitChildRemovedChanged) - self.sigParentChanged.connect(self.emitParentChanged) - self.sigLimitsChanged.connect(self.emitLimitsChanged) - self.sigDefaultChanged.connect(self.emitDefaultChanged) - self.sigNameChanged.connect(self.emitNameChanged) - self.sigOptionsChanged.connect(self.emitOptionsChanged) - self.sigContextMenu.connect(self.emitContextMenuChanged) + self.sigValueChanged.connect(self._emitValueChanged) + self.sigChildAdded.connect(self._emitChildAddedChanged) + self.sigChildRemoved.connect(self._emitChildRemovedChanged) + self.sigParentChanged.connect(self._emitParentChanged) + self.sigLimitsChanged.connect(self._emitLimitsChanged) + self.sigDefaultChanged.connect(self._emitDefaultChanged) + self.sigNameChanged.connect(self._emitNameChanged) + self.sigOptionsChanged.connect(self._emitOptionsChanged) + self.sigContextMenu.connect(self._emitContextMenuChanged) #self.watchParam(self) ## emit treechange signals if our own state changes @@ -511,31 +511,31 @@ class Parameter(QtCore.QObject): self.treeStateChanges.append((self, changeDesc, data)) self.emitTreeChanges() - def emitValueChanged(self, param, data): + def _emitValueChanged(self, param, data): self.emitStateChanged("value", data) - def emitChildAddedChanged(self, param, *data): + def _emitChildAddedChanged(self, param, *data): self.emitStateChanged("childAdded", data) - def emitChildRemovedChanged(self, param, data): + def _emitChildRemovedChanged(self, param, data): self.emitStateChanged("childRemoved", data) - def emitParentChanged(self, param, data): + def _emitParentChanged(self, param, data): self.emitStateChanged("parent", data) - def emitLimitsChanged(self, param, data): + def _emitLimitsChanged(self, param, data): self.emitStateChanged("limits", data) - def emitDefaultChanged(self, param, data): + def _emitDefaultChanged(self, param, data): self.emitStateChanged("default", data) - def emitNameChanged(self, param, data): + def _emitNameChanged(self, param, data): self.emitStateChanged("name", data) - def emitOptionsChanged(self, param, data): + def _emitOptionsChanged(self, param, data): self.emitStateChanged("options", data) - def emitContextMenuChanged(self, param, data): + def _emitContextMenuChanged(self, param, data): self.emitStateChanged("contextMenu", data) def makeTreeItem(self, depth):