From 7ba8863d6a0c21f772e4ef8a5d4180c2a7ab49cb Mon Sep 17 00:00:00 2001 From: wakonig_k Date: Fri, 27 Jun 2025 18:19:49 +0200 Subject: [PATCH] fix(signal input base): unregister callback to avoid accessing deleted qt objects --- .../base_classes/device_signal_input_base.py | 9 ++++++++- tests/unit_tests/test_device_signal_input.py | 9 +++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/bec_widgets/widgets/control/device_input/base_classes/device_signal_input_base.py b/bec_widgets/widgets/control/device_input/base_classes/device_signal_input_base.py index 89424e52..21670749 100644 --- a/bec_widgets/widgets/control/device_input/base_classes/device_signal_input_base.py +++ b/bec_widgets/widgets/control/device_input/base_classes/device_signal_input_base.py @@ -55,7 +55,7 @@ class DeviceSignalInputBase(BECWidget): self._hinted_signals = [] self._normal_signals = [] self._config_signals = [] - self.bec_dispatcher.client.callbacks.register( + self._device_update_register = self.bec_dispatcher.client.callbacks.register( EventType.DEVICE_UPDATE, self.update_signals_from_filters ) @@ -289,3 +289,10 @@ class DeviceSignalInputBase(BECWidget): if config is None: return DeviceSignalInputBaseConfig(widget_class=self.__class__.__name__) return DeviceSignalInputBaseConfig.model_validate(config) + + def cleanup(self): + """ + Cleanup the widget. + """ + self.bec_dispatcher.client.callbacks.remove(self._device_update_register) + super().cleanup() diff --git a/tests/unit_tests/test_device_signal_input.py b/tests/unit_tests/test_device_signal_input.py index e76def1a..65bffd23 100644 --- a/tests/unit_tests/test_device_signal_input.py +++ b/tests/unit_tests/test_device_signal_input.py @@ -144,3 +144,12 @@ def test_signal_lineedit(device_signal_line_edit): assert device_signal_line_edit._is_valid_input is True device_signal_line_edit.setText("invalid") assert device_signal_line_edit._is_valid_input is False + + +def test_device_signal_input_base_cleanup(qtbot, mocked_client): + + widget = DeviceInputWidget(client=mocked_client) + widget.close() + widget.deleteLater() + + mocked_client.callbacks.remove.assert_called_once_with(widget._device_update_register)