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 af1ecbad..b80227be 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 @@ -5,6 +5,7 @@ from qtpy.QtGui import QPainter, QPaintEvent, QPen from qtpy.QtWidgets import QComboBox, QSizePolicy from bec_widgets.utils.colors import get_accent_colors +from bec_widgets.utils.error_popups import SafeProperty from bec_widgets.widgets.control.device_input.base_classes.device_input_base import ( BECDeviceFilter, DeviceInputBase, @@ -61,6 +62,7 @@ class DeviceComboBox(DeviceInputBase, QComboBox): self._callback_id = None self._is_valid_input = False self._accent_colors = get_accent_colors() + self._set_first_element_as_empty = False # We do not consider the config that is passed here, this produced problems # with QtDesigner, since config and input arguments may differ and resolve properly # Implementing this logic and config recoverage is postponed. @@ -93,6 +95,31 @@ class DeviceComboBox(DeviceInputBase, QComboBox): self.currentTextChanged.connect(self.check_validity) self.check_validity(self.currentText()) + @SafeProperty(bool) + def set_first_element_as_empty(self) -> bool: + """ + Whether the first element in the combobox should be empty. + This is useful to allow the user to select a device from the list. + """ + return self._set_first_element_as_empty + + @set_first_element_as_empty.setter + def set_first_element_as_empty(self, value: bool) -> None: + """ + Set whether the first element in the combobox should be empty. + This is useful to allow the user to select a device from the list. + + Args: + value (bool): True if the first element should be empty, False otherwise. + """ + self._set_first_element_as_empty = value + if self._set_first_element_as_empty: + self.insertItem(0, "") + self.setCurrentIndex(0) + else: + if self.count() > 0 and self.itemText(0) == "": + self.removeItem(0) + def on_device_update(self, action: str, content: dict) -> None: """ Callback for device update events. Triggers the device_update signal. 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 17461d4d..7c0bdadd 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 @@ -1,8 +1,10 @@ +from __future__ import annotations + from bec_lib.device import Positioner from qtpy.QtCore import QSize, Signal from qtpy.QtWidgets import QComboBox, QSizePolicy -from bec_widgets.utils.error_popups import SafeSlot +from bec_widgets.utils.error_popups import SafeProperty, SafeSlot from bec_widgets.utils.filter_io import ComboBoxFilterHandler, FilterIO from bec_widgets.utils.ophyd_kind_util import Kind from bec_widgets.widgets.control.device_input.base_classes.device_signal_input_base import ( @@ -54,6 +56,7 @@ class SignalComboBox(DeviceSignalInputBase, QComboBox): self.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed) self.setMinimumSize(QSize(100, 0)) + self._set_first_element_as_empty = True # We do not consider the config that is passed here, this produced problems # with QtDesigner, since config and input arguments may differ and resolve properly # Implementing this logic and config recoverage is postponed. @@ -90,6 +93,31 @@ class SignalComboBox(DeviceSignalInputBase, QComboBox): self.insertItem(0, "Hinted Signals") self.model().item(0).setEnabled(False) + @SafeProperty(bool) + def set_first_element_as_empty(self) -> bool: + """ + Whether the first element in the combobox should be empty. + This is useful to allow the user to select a device from the list. + """ + return self._set_first_element_as_empty + + @set_first_element_as_empty.setter + def set_first_element_as_empty(self, value: bool) -> None: + """ + Set whether the first element in the combobox should be empty. + This is useful to allow the user to select a device from the list. + + Args: + value (bool): True if the first element should be empty, False otherwise. + """ + self._set_first_element_as_empty = value + if self._set_first_element_as_empty: + self.insertItem(0, "") + self.setCurrentIndex(0) + else: + if self.count() > 0 and self.itemText(0) == "": + self.removeItem(0) + def set_to_obj_name(self, obj_name: str) -> bool: """ Set the combobox to the object name of the signal.