From bab70012f9ed7ac3ec714e1d38c46a4b1adc486e Mon Sep 17 00:00:00 2001 From: wakonig_k Date: Wed, 20 May 2026 17:30:17 +0200 Subject: [PATCH] fix(bec-dispatcher): add disconnect_owner method to manage widget slot disconnections --- bec_widgets/utils/bec_dispatcher.py | 18 ++++++++++++++++++ bec_widgets/utils/bec_widget.py | 1 + 2 files changed, 19 insertions(+) diff --git a/bec_widgets/utils/bec_dispatcher.py b/bec_widgets/utils/bec_dispatcher.py index 6f145315..c62cb521 100644 --- a/bec_widgets/utils/bec_dispatcher.py +++ b/bec_widgets/utils/bec_dispatcher.py @@ -24,6 +24,7 @@ logger = bec_logger.logger if TYPE_CHECKING: # pragma: no cover from bec_lib.endpoints import EndpointInfo + from bec_widgets.utils.bec_widget import BECWidget from bec_widgets.utils.rpc_server import RPCServer @@ -77,6 +78,7 @@ class QtThreadSafeCallback(QObject): self.cb_info = cb_info self.cb = cb + self.cb_owner = louie.saferef.safe_ref(cb.__self__) if hasattr(cb, "__self__") else None self.cb_ref = louie.saferef.safe_ref(cb) self.cb_signal.connect(self.cb) self.topics = set() @@ -277,6 +279,22 @@ class BECDispatcher: # pylint: disable=protected-access self.disconnect_topics(self.client.connector._topics_cb) + def disconnect_owner(self, owner: BECWidget): + """ + Disconnect all slots owned by a particular widget. + + Args: + owner(BECWidget): The owner widget whose slots should be disconnected + """ + slots_to_disconnect = [] + for connected_slot in self._registered_slots.values(): + if connected_slot.cb_owner is not None and connected_slot.cb_owner() == owner: + slots_to_disconnect.append(connected_slot) + for slot in slots_to_disconnect: + topics = slot.topics.copy() + for topic in topics: + self.disconnect_slot(slot.cb, topic) + def start_cli_server(self, gui_id: str | None = None): """ Start the CLI server. diff --git a/bec_widgets/utils/bec_widget.py b/bec_widgets/utils/bec_widget.py index 6f254aab..543fde76 100644 --- a/bec_widgets/utils/bec_widget.py +++ b/bec_widgets/utils/bec_widget.py @@ -364,6 +364,7 @@ class BECWidget(BECConnector): """Wrap the close even to ensure the rpc_register is cleaned up.""" try: if not self._destroyed: + self.bec_dispatcher.disconnect_owner(self) self.cleanup() self._destroyed = True finally: