diff --git a/bec_widgets/widgets/control/device_input/device_combobox/device_combobox.py b/bec_widgets/widgets/control/device_input/device_combobox/device_combobox.py index 1700b3e1..9ebffa4e 100644 --- a/bec_widgets/widgets/control/device_input/device_combobox/device_combobox.py +++ b/bec_widgets/widgets/control/device_input/device_combobox/device_combobox.py @@ -496,6 +496,7 @@ class DeviceComboBox(BECWidget, QComboBox): """Cleanup the widget.""" if self._callback_id is not None: self.bec_dispatcher.client.callbacks.remove(self._callback_id) + self._callback_id = None super().cleanup() def get_current_device(self) -> object: diff --git a/bec_widgets/widgets/control/device_input/signal_combobox/signal_combobox.py b/bec_widgets/widgets/control/device_input/signal_combobox/signal_combobox.py index 89478694..03dc0836 100644 --- a/bec_widgets/widgets/control/device_input/signal_combobox/signal_combobox.py +++ b/bec_widgets/widgets/control/device_input/signal_combobox/signal_combobox.py @@ -588,7 +588,9 @@ class SignalComboBox(BECWidget, QComboBox): def cleanup(self): """Cleanup the widget.""" - self.bec_dispatcher.client.callbacks.remove(self._device_update_register) + if self._device_update_register is not None: + self.bec_dispatcher.client.callbacks.remove(self._device_update_register) + self._device_update_register = None super().cleanup() @staticmethod diff --git a/tests/unit_tests/test_device_input_widgets.py b/tests/unit_tests/test_device_input_widgets.py index 78763071..b5927c5e 100644 --- a/tests/unit_tests/test_device_input_widgets.py +++ b/tests/unit_tests/test_device_input_widgets.py @@ -1,3 +1,5 @@ +from unittest import mock + import pytest from bec_lib.device import ReadoutPriority @@ -124,6 +126,19 @@ def test_device_input_combobox_disabled_invalid_has_neutral_border(device_input_ assert "red" in device_input_combobox.styleSheet() +def test_device_input_combobox_cleanup_unregisters_callback(qtbot, mocked_client): + with mock.patch.object(mocked_client.callbacks, "remove"): + widget = DeviceComboBox(client=mocked_client) + qtbot.addWidget(widget) + callback_id = widget._callback_id + + widget.close() + widget.deleteLater() + + mocked_client.callbacks.remove.assert_called_once_with(callback_id) + assert widget._callback_id is None + + def test_get_device_from_input_combobox_init(device_input_combobox): device_input_combobox.setCurrentIndex(0) device_text = device_input_combobox.currentText() diff --git a/tests/unit_tests/test_device_signal_input.py b/tests/unit_tests/test_device_signal_input.py index 836e3f4e..743a8140 100644 --- a/tests/unit_tests/test_device_signal_input.py +++ b/tests/unit_tests/test_device_signal_input.py @@ -188,10 +188,12 @@ def test_linked_device_combobox_updates_signal_combobox_on_each_text_change( def test_device_signal_input_base_cleanup(qtbot, mocked_client): with mock.patch.object(mocked_client.callbacks, "remove"): widget = SignalComboBox(client=mocked_client) + callback_id = widget._device_update_register widget.close() widget.deleteLater() - mocked_client.callbacks.remove.assert_called_once_with(widget._device_update_register) + mocked_client.callbacks.remove.assert_called_once_with(callback_id) + assert widget._device_update_register is None def test_signal_combobox_get_signal_name_with_item_data(qtbot, device_signal_combobox):