diff --git a/fsl/props/build.py b/fsl/props/build.py index addfc5e9a5de0cc804a66aeae2a9bacf43630c96..4020f041b41461ab9c9679a79e3aa030091fcd22 100644 --- a/fsl/props/build.py +++ b/fsl/props/build.py @@ -651,10 +651,15 @@ def _prepareEvents(hasProps, propGui): onChange() # add a callback listener to every property + lName = 'build_py_WhenEvent' for propObj, propName in zip(propObjs, propNames): - - lName = 'build_py_WhenEvent' propObj.addListener(hasProps, lName, onChange) + + def removeListeners(ev): + for propObj, propName in zip(propObjs, propNames): + propObj.removeListener(hasProps, lName) + + propGui.topLevel.Bind(wx.EVT_WINDOW_DESTROY, removeListeners) def buildGUI(parent, diff --git a/fsl/props/widgets.py b/fsl/props/widgets.py index d5c528c6aa3a094f80244d5c7b08ee2b7747c68d..08c29b4a895c99611d2e71befe663b6fba986bda 100644 --- a/fsl/props/widgets.py +++ b/fsl/props/widgets.py @@ -111,11 +111,7 @@ def _propBind(hasProps, propObj, propVal, guiObj, evType, labelMap=None): is changed. Updates the property value. """ - # TODO remove property value listener when GUI object is destroyed - try: - value = guiObj.GetValue() - except: - raise + value = guiObj.GetValue() if propVal.get() == value: return @@ -128,6 +124,11 @@ def _propBind(hasProps, propObj, propVal, guiObj, evType, labelMap=None): for ev in evType: guiObj.Bind(ev, _propUpdate) propVal.addListener(listenerName, _guiUpdate) + guiObj.Bind(wx.EVT_WINDOW_DESTROY, + lambda ev: propVal.removeListener(listenerName)) + + + def _setupValidation(widget, hasProps, propObj, propVal): """ @@ -160,9 +161,13 @@ def _setupValidation(widget, hasProps, propObj, propVal): # associated with multiple variables, and we don't want # the widgets associated with those other variables to # change background. - propVal.addListener( - 'widgets_py_ChangeBG_{}'.format(id(widget)), - _changeBGOnValidate) + lName = 'widgets_py_ChangeBG_{}'.format(id(widget)) + propVal.addListener(lName, _changeBGOnValidate) + + # And ensure that the listener is + # removed when the widget is destroyed + widget.Bind(wx.EVT_WINDOW_DESTROY, + lambda ev: propVal.removeListener(lName)) # Validate the initial property value, # so the background is appropriately set