From ae9daff6ed546a98ac064207dc5bb4c025cccfde Mon Sep 17 00:00:00 2001 From: wyzula-jan Date: Wed, 20 May 2026 17:30:36 +0200 Subject: [PATCH] wip queued connections for device inputs --- .../device_combobox/device_combobox.py | 12 +++++++++-- .../signal_combobox/signal_combobox.py | 20 +++++++++++++++++-- 2 files changed, 28 insertions(+), 4 deletions(-) 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..256b6b9a 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 @@ -9,7 +9,7 @@ from bec_lib.device import ComputedSignal, Device, Positioner, ReadoutPriority from bec_lib.device import Signal as BECSignal from bec_lib.logger import bec_logger from pydantic import Field, field_validator -from qtpy.QtCore import QSize, QStringListModel, Signal, Slot +from qtpy.QtCore import QSize, QStringListModel, Qt, Signal, Slot from qtpy.QtWidgets import QComboBox, QCompleter, QSizePolicy from bec_widgets.utils.bec_connector import ConnectionConfig @@ -219,7 +219,9 @@ class DeviceComboBox(BECWidget, QComboBox): self._callback_id = self.bec_dispatcher.client.callbacks.register( EventType.DEVICE_UPDATE, self.on_device_update ) - self.device_config_update.connect(self.update_devices_from_filters) + self.device_config_update.connect( + self.update_devices_from_filters, Qt.ConnectionType.QueuedConnection + ) self.currentTextChanged.connect(self.check_validity) self.check_validity(self.currentText()) @@ -255,6 +257,9 @@ class DeviceComboBox(BECWidget, QComboBox): @SafeSlot() def update_devices_from_filters(self): """Refresh the available device list from current device/readout/signal filters.""" + if getattr(self, "_destroyed", False): + return + self.config.device_filter = [entry.value for entry in self.device_filter] self.config.readout_filter = [entry.value for entry in self.readout_filter] self.config.signal_class_filter = self.signal_class_filter @@ -489,6 +494,8 @@ class DeviceComboBox(BECWidget, QComboBox): action: Device update action emitted by BEC. content: Device update payload. Currently unused. """ + if getattr(self, "_destroyed", False): + return if action in ["add", "remove", "reload"]: self.device_config_update.emit() @@ -496,6 +503,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..28d67389 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 @@ -77,6 +77,7 @@ class SignalComboBox(BECWidget, QComboBox): device_signal_changed = Signal(str) signal_reset = Signal() + device_config_update = Signal() def __init__( self, @@ -138,7 +139,10 @@ class SignalComboBox(BECWidget, QComboBox): self.autocomplete = True self._device_update_register = self.bec_dispatcher.client.callbacks.register( - EventType.DEVICE_UPDATE, self.update_signals_from_filters + EventType.DEVICE_UPDATE, self.on_device_update + ) + self.device_config_update.connect( + self.update_signals_from_filters, Qt.ConnectionType.QueuedConnection ) self.currentTextChanged.connect(self.on_text_changed) @@ -207,6 +211,9 @@ class SignalComboBox(BECWidget, QComboBox): content: Optional callback payload from BEC device updates. Currently unused. metadata: Optional callback metadata from BEC device updates. Currently unused. """ + if getattr(self, "_destroyed", False): + return + self.config.signal_filter = [kind.name for kind in self.signal_filter] if self._signal_class_filter: @@ -247,6 +254,13 @@ class SignalComboBox(BECWidget, QComboBox): ), ) + def on_device_update(self, action: str, content: dict) -> None: + """Refresh filters when BEC reports device configuration changes.""" + if getattr(self, "_destroyed", False): + return + if action in ["add", "remove", "reload"]: + self.device_config_update.emit() + @Property(str) def device(self) -> str: """Selected device.""" @@ -588,7 +602,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