refactor(device_input): consolidation of device/signal combobox logic; docsrtings added

This commit is contained in:
2026-05-15 13:13:31 +02:00
committed by Jan Wyzula
parent 3d934a8c38
commit daa1ba020c
8 changed files with 612 additions and 182 deletions
+51 -14
View File
@@ -2,7 +2,10 @@
from __future__ import annotations
from contextlib import nullcontext
from bec_lib.logger import bec_logger
from qtpy.QtCore import QSignalBlocker
from qtpy.QtWidgets import QComboBox
from typeguard import TypeCheckError
@@ -11,25 +14,49 @@ from bec_widgets.utils.ophyd_kind_util import Kind
logger = bec_logger.logger
def replace_combobox_items(combo_box: QComboBox, items: list[str | tuple]) -> None:
"""Replace all combobox entries with strings or ``(text, data)`` tuples."""
combo_box.clear()
for item in items:
if isinstance(item, str):
combo_box.addItem(item)
else:
combo_box.addItem(*item)
def replace_combobox_items(
combo_box: QComboBox,
items: list[str | tuple],
*,
preserve_current_text: bool = False,
block_signals: bool = False,
) -> None:
"""Replace all combobox entries.
def combobox_contains_text(combo_box: QComboBox, text: str) -> bool:
"""Return whether *text* is present as visible combobox text."""
return any(combo_box.itemText(i) == text for i in range(combo_box.count()))
Args:
combo_box: Combobox whose entries should be replaced.
items: Entries to add. String entries are added as display text. Tuple entries are
passed to ``QComboBox.addItem`` as ``(text, data)``.
preserve_current_text: If True, restore the combobox text after replacing the items.
block_signals: If True, block combobox signals while the items are replaced.
"""
current_text = combo_box.currentText()
signal_blocker = QSignalBlocker(combo_box) if block_signals else nullcontext()
with signal_blocker:
combo_box.clear()
for item in items:
if isinstance(item, str):
combo_box.addItem(item)
else:
combo_box.addItem(*item)
if preserve_current_text:
combo_box.setCurrentText(current_text)
def signal_items_for_kind(
*, kind: Kind, signal_filter: set[Kind], device_info: dict, device_name: str
) -> list[tuple[str, dict]]:
"""Build display entries for signals matching a BEC signal kind."""
"""Build display entries for signals matching a BEC signal kind.
Args:
kind: Signal kind to collect.
signal_filter: Enabled signal kinds.
device_info: Signal metadata from the BEC device info dictionary.
device_name: Name of the device owning the signals.
Returns:
Combobox entries as ``(display_text, signal_info)`` tuples.
"""
items: list[tuple[str, dict]] = []
for signal_name, signal_info in device_info.items():
if kind not in signal_filter or signal_info.get("kind_str") != kind.name:
@@ -54,7 +81,17 @@ def signal_items_for_kind(
def get_bec_signals_for_classes(
*, client, signal_class_filter: str | list[str], ndim_filter: int | list[int] | None = None
) -> list[tuple[str, str, dict]]:
"""Return BEC signals filtered by signal class and optional dimensionality."""
"""Return BEC signals filtered by signal class and optional dimensionality.
Args:
client: BEC client that provides ``device_manager.get_bec_signals``.
signal_class_filter: Signal class name or class names passed to the device manager.
ndim_filter: Optional dimensionality filter. If provided, only signals whose
``describe.signal_info.ndim`` is in this value are returned.
Returns:
Tuples of ``(device_name, signal_name, signal_config)`` for matching signals.
"""
if not client or not hasattr(client, "device_manager"):
return []