From f477bb5838b5a67ed4a8fc3f97ac294019d03c68 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 7bdcddbc..552b832a 100644 --- a/bec_widgets/utils/bec_dispatcher.py +++ b/bec_widgets/utils/bec_dispatcher.py @@ -25,6 +25,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 @@ -78,6 +79,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() @@ -271,6 +273,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 82cf2a27..186e7fde 100644 --- a/bec_widgets/utils/bec_widget.py +++ b/bec_widgets/utils/bec_widget.py @@ -406,6 +406,7 @@ class BECWidget(BECConnector): try: if not self._destroyed: self._destroyed = True + self.bec_dispatcher.disconnect_owner(self) self.cleanup() finally: super().closeEvent(event) # pylint: disable=no-member