From 133c6004447bc562d6bf55562c20e0f6c8700858 Mon Sep 17 00:00:00 2001 From: wyzula-jan Date: Fri, 5 Jun 2026 14:36:57 +0200 Subject: [PATCH] fix(device_input): styling adjusted --- .../device_combobox/device_combobox.py | 6 ++- .../signal_combobox/signal_combobox.py | 37 +++++++++++++++---- tests/unit_tests/test_device_input_widgets.py | 2 +- tests/unit_tests/test_device_signal_input.py | 18 ++++++++- 4 files changed, 52 insertions(+), 11 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 a92350df..5314123d 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 @@ -603,8 +603,10 @@ class DeviceComboBox(BECWidget, QComboBox): return device.readout_priority in self.readout_filter def _update_validity_style(self, is_valid: bool) -> None: - border_color = "transparent" if is_valid or not self.isEnabled() else "red" - self.setStyleSheet(f"border: 1px solid {border_color};") + if is_valid or not self.isEnabled(): + self.setStyleSheet("") + return + self.setStyleSheet("QComboBox { border: 1px solid red; }") def _filter_devices_by_signal_class( self, devices: list[Device | BECSignal | ComputedSignal | Positioner] 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 e2f0e718..46365182 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 @@ -468,8 +468,7 @@ class SignalComboBox(BECWidget, QComboBox): True if an enabled item was found and selected. """ for index in range(self.count()): - item = self.model().item(index) - if item is not None and item.isEnabled(): + if self._item_is_enabled(index): self.setCurrentIndex(index) return True return False @@ -626,8 +625,10 @@ class SignalComboBox(BECWidget, QComboBox): self.check_validity(self.currentText()) def _update_validity_style(self, is_valid: bool) -> None: - border_color = "transparent" if is_valid or not self.isEnabled() else "red" - self.setStyleSheet(f"border: 1px solid {border_color};") + if is_valid or not self.isEnabled(): + self.setStyleSheet("") + return + self.setStyleSheet("QComboBox { border: 1px solid red; }") def _replace_signal_items(self, items: list[str | tuple[str, dict]] | None = None): combo_items = self._signals if items is None else items @@ -648,15 +649,37 @@ class SignalComboBox(BECWidget, QComboBox): if self._config_signals: index = offset + len(self._hinted_signals) + len(self._normal_signals) self.insertItem(index, "Config Signals") - self.model().item(index).setEnabled(False) + self._set_item_enabled(index, False) if self._normal_signals: index = offset + len(self._hinted_signals) self.insertItem(index, "Normal Signals") - self.model().item(index).setEnabled(False) + self._set_item_enabled(index, False) if self._hinted_signals: index = offset self.insertItem(index, "Hinted Signals") - self.model().item(index).setEnabled(False) + self._set_item_enabled(index, False) + + def _standard_item(self, index: int): + model = self.model() + item_getter = getattr(model, "item", None) + if callable(item_getter): + return item_getter(index) + return None + + def _item_is_enabled(self, index: int) -> bool: + item = self._standard_item(index) + if item is not None: + return item.isEnabled() + + model_index = self.model().index(index, self.modelColumn()) + if not model_index.isValid(): + return True + return bool(self.model().flags(model_index) & Qt.ItemFlag.ItemIsEnabled) + + def _set_item_enabled(self, index: int, enabled: bool) -> None: + item = self._standard_item(index) + if item is not None: + item.setEnabled(enabled) def _display_text_for_signal(self, signal: str) -> str | None: for entry in self._signals: diff --git a/tests/unit_tests/test_device_input_widgets.py b/tests/unit_tests/test_device_input_widgets.py index 767d741e..880759a9 100644 --- a/tests/unit_tests/test_device_input_widgets.py +++ b/tests/unit_tests/test_device_input_widgets.py @@ -120,7 +120,7 @@ def test_device_input_combobox_disabled_invalid_has_neutral_border(device_input_ assert "red" in device_input_combobox.styleSheet() device_input_combobox.setEnabled(False) - assert "transparent" in device_input_combobox.styleSheet() + assert device_input_combobox.styleSheet() == "" device_input_combobox.setEnabled(True) assert "red" in device_input_combobox.styleSheet() diff --git a/tests/unit_tests/test_device_signal_input.py b/tests/unit_tests/test_device_signal_input.py index 36b9111a..7a37495a 100644 --- a/tests/unit_tests/test_device_signal_input.py +++ b/tests/unit_tests/test_device_signal_input.py @@ -96,6 +96,22 @@ def test_signal_combobox_autocomplete(qtbot, mocked_client): assert text_changes[-1] == "manual_signal" +def test_signal_combobox_group_headers_are_disabled(qtbot, mocked_client): + widget = create_widget(qtbot=qtbot, widget=SignalComboBox, client=mocked_client) + + widget.set_device("samx") + + assert widget.itemText(0) == "Hinted Signals" + assert widget.itemText(2) == "Normal Signals" + assert widget.itemText(4) == "Config Signals" + assert widget.model().item(0).isEnabled() is False + assert widget.model().item(2).isEnabled() is False + assert widget.model().item(4).isEnabled() is False + + assert widget.set_to_first_enabled() is True + assert widget.currentText() == "samx (readback)" + + def test_signal_combobox_qproperties(device_signal_combobox): device_signal_combobox.include_config_signals = False device_signal_combobox.include_normal_signals = False @@ -116,7 +132,7 @@ def test_signal_combobox_disabled_invalid_has_neutral_border(device_signal_combo assert "red" in device_signal_combobox.styleSheet() device_signal_combobox.setEnabled(False) - assert "transparent" in device_signal_combobox.styleSheet() + assert device_signal_combobox.styleSheet() == "" device_signal_combobox.setEnabled(True) assert "red" in device_signal_combobox.styleSheet()