mirror of
https://github.com/bec-project/bec_widgets.git
synced 2025-07-13 19:21:50 +02:00
refactor: cleanup, added device_signal for signal inputs
This commit is contained in:
@ -217,7 +217,7 @@ DEVICES = [
|
||||
FakeDevice("bpm4i"),
|
||||
FakeDevice("bpm3a"),
|
||||
FakeDevice("bpm3i"),
|
||||
FakeDevice("eiger"),
|
||||
FakeDevice("eiger", readout_priority=ReadoutPriority.ASYNC),
|
||||
FakeDevice("waveform1d"),
|
||||
FakeDevice("async_device", readout_priority=ReadoutPriority.ASYNC),
|
||||
Positioner("test", limits=[-10, 10], read_value=2.0),
|
||||
|
@ -99,7 +99,7 @@ class FilterIO:
|
||||
_handlers = {QLineEdit: LineEditFilterHandler, QComboBox: ComboBoxFilterHandler}
|
||||
|
||||
@staticmethod
|
||||
def set_selection(widget, selection: list, ignore_errors=False):
|
||||
def set_selection(widget, selection: list, ignore_errors=True):
|
||||
"""
|
||||
Retrieve value from the widget instance.
|
||||
|
||||
@ -118,7 +118,7 @@ class FilterIO:
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def check_input(widget, text: str, ignore_errors=False):
|
||||
def check_input(widget, text: str, ignore_errors=True):
|
||||
"""
|
||||
Check if the input text is in the filtered selection.
|
||||
|
||||
|
@ -5,7 +5,6 @@ import enum
|
||||
from bec_lib.device import ComputedSignal, Device, Positioner, ReadoutPriority, Signal
|
||||
from bec_lib.logger import bec_logger
|
||||
from qtpy.QtCore import Property, Slot
|
||||
from typeguard import typechecked
|
||||
|
||||
from bec_widgets.utils import ConnectionConfig
|
||||
from bec_widgets.utils.bec_widget import BECWidget
|
||||
@ -25,11 +24,12 @@ class BECDeviceFilter(enum.Enum):
|
||||
|
||||
|
||||
class DeviceInputConfig(ConnectionConfig):
|
||||
device_filter: list[BECDeviceFilter] | None = None
|
||||
readout_filter: list[ReadoutPriority] | None = None
|
||||
devices: list[str] | None = None
|
||||
device_filter: list[BECDeviceFilter] = []
|
||||
readout_filter: list[ReadoutPriority] = []
|
||||
devices: list[str] = []
|
||||
default: str | None = None
|
||||
arg_name: str | None = None
|
||||
apply_filter: bool = True
|
||||
|
||||
|
||||
class DeviceInputBase(BECWidget):
|
||||
@ -47,10 +47,10 @@ class DeviceInputBase(BECWidget):
|
||||
}
|
||||
|
||||
_filter_handler = {
|
||||
BECDeviceFilter.DEVICE: "include_device",
|
||||
BECDeviceFilter.POSITIONER: "include_positioner",
|
||||
BECDeviceFilter.SIGNAL: "include_signal",
|
||||
BECDeviceFilter.COMPUTED_SIGNAL: "include_computed_signal",
|
||||
BECDeviceFilter.DEVICE: "filter_to_device",
|
||||
BECDeviceFilter.POSITIONER: "filter_to_positioner",
|
||||
BECDeviceFilter.SIGNAL: "filter_to_signal",
|
||||
BECDeviceFilter.COMPUTED_SIGNAL: "filter_to_computed_signal",
|
||||
ReadoutPriority.MONITORED: "readout_monitored",
|
||||
ReadoutPriority.BASELINE: "readout_baseline",
|
||||
ReadoutPriority.ASYNC: "readout_async",
|
||||
@ -66,7 +66,7 @@ class DeviceInputBase(BECWidget):
|
||||
if isinstance(config, dict):
|
||||
config = DeviceInputConfig(**config)
|
||||
self.config = config
|
||||
super().__init__(client=client, config=config, gui_id=gui_id)
|
||||
super().__init__(client=client, config=config, gui_id=gui_id, theme_update=True)
|
||||
self.get_bec_shortcuts()
|
||||
self._device_filter = []
|
||||
self._readout_filter = []
|
||||
@ -82,7 +82,7 @@ class DeviceInputBase(BECWidget):
|
||||
Args:
|
||||
device (str): Default name.
|
||||
"""
|
||||
if self.validate_device(device, raise_on_false=True) is True:
|
||||
if self.validate_device(device) is True:
|
||||
WidgetIO.set_value(widget=self, value=device)
|
||||
self.config.default = device
|
||||
else:
|
||||
@ -91,9 +91,13 @@ class DeviceInputBase(BECWidget):
|
||||
@Slot()
|
||||
def update_devices_from_filters(self):
|
||||
"""Update the devices based on the current filter selection
|
||||
in self.device_filter and self.readout_filter."""
|
||||
in self.device_filter and self.readout_filter. If apply_filter is False,
|
||||
it will not apply the filters, store the filter settings and return.
|
||||
"""
|
||||
self.config.device_filter = self.device_filter
|
||||
self.config.readout_filter = self.readout_filter
|
||||
if self.apply_filter is False:
|
||||
return
|
||||
all_dev = self.dev.enabled_devices
|
||||
# Filter based on device class
|
||||
devs = [dev for dev in all_dev if self._check_device_filter(dev)]
|
||||
@ -109,16 +113,37 @@ class DeviceInputBase(BECWidget):
|
||||
Args:
|
||||
devices (list[str]): List of devices.
|
||||
"""
|
||||
valid_dev = []
|
||||
all_dev_names = [dev.name for dev in self.dev.enabled_devices]
|
||||
for device in devices:
|
||||
if device not in all_dev_names:
|
||||
continue
|
||||
valid_dev.append(device)
|
||||
self.devices = valid_dev
|
||||
self.apply_filter = False
|
||||
self.devices = devices
|
||||
|
||||
### QtProperties ###
|
||||
|
||||
@Property(
|
||||
"QStringList",
|
||||
doc="List of devices. If updated, it will disable the apply filters property.",
|
||||
)
|
||||
def devices(self) -> list[str]:
|
||||
"""
|
||||
Get the list of devices for the applied filters.
|
||||
|
||||
Returns:
|
||||
list[str]: List of devices.
|
||||
"""
|
||||
return self._devices
|
||||
|
||||
@devices.setter
|
||||
def devices(self, value: list):
|
||||
valid_dev = []
|
||||
all_dev_names = [dev.name for dev in self.dev.enabled_devices]
|
||||
for dev in value:
|
||||
if dev in all_dev_names:
|
||||
valid_dev.append(dev)
|
||||
self._devices = valid_dev
|
||||
self.config.devices = valid_dev
|
||||
|
||||
FilterIO.set_selection(widget=self, selection=valid_dev)
|
||||
# QTimer.singleShot(200, lambda: FilterIO.set_selection(widget=self, selection=valid_dev))
|
||||
|
||||
@Property(str)
|
||||
def default(self):
|
||||
"""Get the default device name. If set through this property, it will update only if the device is within the filtered selection."""
|
||||
@ -126,30 +151,52 @@ class DeviceInputBase(BECWidget):
|
||||
|
||||
@default.setter
|
||||
def default(self, value: str):
|
||||
if self.validate_device(value, raise_on_false=False) is False:
|
||||
return
|
||||
self.set_device(value)
|
||||
def set_default():
|
||||
if self.validate_device(value) is False:
|
||||
return
|
||||
self.set_device(value)
|
||||
|
||||
set_default()
|
||||
# QTimer.singleShot(200, set_default)
|
||||
|
||||
@Property(bool)
|
||||
def include_device(self):
|
||||
def apply_filter(self):
|
||||
"""Apply the filters on the devices."""
|
||||
return self.config.apply_filter
|
||||
|
||||
@apply_filter.setter
|
||||
def apply_filter(self, value: bool):
|
||||
def apply_filters():
|
||||
self.config.apply_filter = value
|
||||
self.update_devices_from_filters()
|
||||
|
||||
apply_filters()
|
||||
# QTimer.singleShot(200, apply_filters)
|
||||
|
||||
@Property(bool)
|
||||
def filter_to_device(self):
|
||||
"""Include devices in filters."""
|
||||
return BECDeviceFilter.DEVICE in self.device_filter
|
||||
|
||||
@include_device.setter
|
||||
def include_device(self, value: bool):
|
||||
if value is True and BECDeviceFilter.DEVICE not in self.device_filter:
|
||||
self._device_filter.append(BECDeviceFilter.DEVICE)
|
||||
if value is False and BECDeviceFilter.DEVICE in self.device_filter:
|
||||
self._device_filter.remove(BECDeviceFilter.DEVICE)
|
||||
self.update_devices_from_filters()
|
||||
@filter_to_device.setter
|
||||
def filter_to_device(self, value: bool):
|
||||
def set_filter():
|
||||
if value is True and BECDeviceFilter.DEVICE not in self.device_filter:
|
||||
self._device_filter.append(BECDeviceFilter.DEVICE)
|
||||
if value is False and BECDeviceFilter.DEVICE in self.device_filter:
|
||||
self._device_filter.remove(BECDeviceFilter.DEVICE)
|
||||
self.update_devices_from_filters()
|
||||
|
||||
set_filter()
|
||||
# QTimer.singleShot(200, set_filter)
|
||||
|
||||
@Property(bool)
|
||||
def include_positioner(self):
|
||||
def filter_to_positioner(self):
|
||||
"""Include devices of type Positioner in filters."""
|
||||
return BECDeviceFilter.POSITIONER in self.device_filter
|
||||
|
||||
@include_positioner.setter
|
||||
def include_positioner(self, value: bool):
|
||||
@filter_to_positioner.setter
|
||||
def filter_to_positioner(self, value: bool):
|
||||
if value is True and BECDeviceFilter.POSITIONER not in self.device_filter:
|
||||
self._device_filter.append(BECDeviceFilter.POSITIONER)
|
||||
if value is False and BECDeviceFilter.POSITIONER in self.device_filter:
|
||||
@ -157,12 +204,12 @@ class DeviceInputBase(BECWidget):
|
||||
self.update_devices_from_filters()
|
||||
|
||||
@Property(bool)
|
||||
def include_signal(self):
|
||||
def filter_to_signal(self):
|
||||
"""Include devices of type Signal in filters."""
|
||||
return BECDeviceFilter.SIGNAL in self.device_filter
|
||||
|
||||
@include_signal.setter
|
||||
def include_signal(self, value: bool):
|
||||
@filter_to_signal.setter
|
||||
def filter_to_signal(self, value: bool):
|
||||
if value is True and BECDeviceFilter.SIGNAL not in self.device_filter:
|
||||
self._device_filter.append(BECDeviceFilter.SIGNAL)
|
||||
if value is False and BECDeviceFilter.SIGNAL in self.device_filter:
|
||||
@ -170,12 +217,12 @@ class DeviceInputBase(BECWidget):
|
||||
self.update_devices_from_filters()
|
||||
|
||||
@Property(bool)
|
||||
def include_computed_signal(self):
|
||||
def filter_to_computed_signal(self):
|
||||
"""Include devices of type ComputedSignal in filters."""
|
||||
return BECDeviceFilter.COMPUTED_SIGNAL in self.device_filter
|
||||
|
||||
@include_computed_signal.setter
|
||||
def include_computed_signal(self, value: bool):
|
||||
@filter_to_computed_signal.setter
|
||||
def filter_to_computed_signal(self, value: bool):
|
||||
if value is True and BECDeviceFilter.COMPUTED_SIGNAL not in self.device_filter:
|
||||
self._device_filter.append(BECDeviceFilter.COMPUTED_SIGNAL)
|
||||
if value is False and BECDeviceFilter.COMPUTED_SIGNAL in self.device_filter:
|
||||
@ -249,22 +296,6 @@ class DeviceInputBase(BECWidget):
|
||||
|
||||
### Python Methods and Properties ###
|
||||
|
||||
@property
|
||||
def devices(self) -> list[str]:
|
||||
"""
|
||||
Get the list of devices for the applied filters.
|
||||
|
||||
Returns:
|
||||
list[str]: List of devices.
|
||||
"""
|
||||
return self._devices
|
||||
|
||||
@devices.setter
|
||||
def devices(self, value: list[str]):
|
||||
self._devices = value
|
||||
self.config.devices = value
|
||||
FilterIO.set_selection(widget=self, selection=value)
|
||||
|
||||
@property
|
||||
def device_filter(self) -> list[object]:
|
||||
"""Get the list of filters to apply on the devices."""
|
||||
@ -283,7 +314,6 @@ class DeviceInputBase(BECWidget):
|
||||
"""Get the available readout priority filters."""
|
||||
return [entry for entry in ReadoutPriority]
|
||||
|
||||
@typechecked
|
||||
def set_device_filter(
|
||||
self, filter_selection: str | BECDeviceFilter | list[str] | list[BECDeviceFilter]
|
||||
):
|
||||
@ -299,11 +329,11 @@ class DeviceInputBase(BECWidget):
|
||||
if isinstance(filter_selection, str) or isinstance(filter_selection, BECDeviceFilter):
|
||||
filters = [self._filter_handler.get(filter_selection)]
|
||||
if filters is None or any([entry is None for entry in filters]):
|
||||
raise ValueError(f"Device filter {filter_selection} is not in the device list.")
|
||||
logger.warning(f"Device filter {filter_selection} is not in the device filter list.")
|
||||
return
|
||||
for entry in filters:
|
||||
setattr(self, entry, True)
|
||||
|
||||
@typechecked
|
||||
def set_readout_priority_filter(
|
||||
self, filter_selection: str | ReadoutPriority | list[str] | list[ReadoutPriority]
|
||||
):
|
||||
@ -319,30 +349,27 @@ class DeviceInputBase(BECWidget):
|
||||
if isinstance(filter_selection, str) or isinstance(filter_selection, ReadoutPriority):
|
||||
filters = [self._filter_handler.get(filter_selection)]
|
||||
if filters is None or any([entry is None for entry in filters]):
|
||||
raise ValueError(
|
||||
logger.warning(
|
||||
f"Readout priority filter {filter_selection} is not in the readout priority list."
|
||||
)
|
||||
return
|
||||
for entry in filters:
|
||||
setattr(self, entry, True)
|
||||
|
||||
def _check_device_filter(self, device: Device | Signal | ComputedSignal | Positioner) -> bool:
|
||||
"""If filters are defined, return True. Else return if the device complies to all active filters.
|
||||
"""Check if filter for device type is applied or not.
|
||||
|
||||
Args:
|
||||
device(Device | Signal | ComputedSignal | Positioner): Device object.
|
||||
"""
|
||||
if len(self.device_filter) == 0:
|
||||
return True
|
||||
return all(isinstance(device, self._device_handler[entry]) for entry in self.device_filter)
|
||||
|
||||
def _check_readout_filter(self, device: Device | Signal | ComputedSignal | Positioner) -> bool:
|
||||
"""If filters are defined, return True. Else return if the device complies to all active filters.
|
||||
"""Check if filter for readout priority is applied or not.
|
||||
|
||||
Args:
|
||||
device(Device | Signal | ComputedSignal | Positioner): Device object.
|
||||
"""
|
||||
if len(self.readout_filter) == 0:
|
||||
return True
|
||||
return device.readout_priority in self.readout_filter
|
||||
|
||||
def get_device_object(self, device: str) -> object:
|
||||
@ -363,7 +390,7 @@ class DeviceInputBase(BECWidget):
|
||||
)
|
||||
return dev
|
||||
|
||||
def validate_device(self, device: str, raise_on_false: bool = False) -> bool:
|
||||
def validate_device(self, device: str) -> bool:
|
||||
"""
|
||||
Validate the device if it is present in the filtered device selection.
|
||||
|
||||
@ -372,5 +399,4 @@ class DeviceInputBase(BECWidget):
|
||||
"""
|
||||
if device in self.devices:
|
||||
return True
|
||||
if raise_on_false is True:
|
||||
raise ValueError(f"Device {device} is not in filtered selection.")
|
||||
return False
|
||||
|
@ -1,6 +1,6 @@
|
||||
import enum
|
||||
|
||||
from bec_lib.device import Signal
|
||||
from bec_lib.logger import bec_logger
|
||||
from ophyd import Kind
|
||||
from qtpy.QtCore import Property, Slot
|
||||
|
||||
from bec_widgets.utils import ConnectionConfig
|
||||
@ -11,14 +11,6 @@ from bec_widgets.utils.widget_io import WidgetIO
|
||||
logger = bec_logger.logger
|
||||
|
||||
|
||||
class BECSignalFilter(str, enum.Enum):
|
||||
"""Filter for the device signals."""
|
||||
|
||||
HINTED = "5"
|
||||
NORMAL = "1"
|
||||
CONFIG = "2"
|
||||
|
||||
|
||||
class DeviceSignalInputBaseConfig(ConnectionConfig):
|
||||
"""Configuration class for DeviceSignalInputBase."""
|
||||
|
||||
@ -37,9 +29,9 @@ class DeviceSignalInputBase(BECWidget):
|
||||
"""
|
||||
|
||||
_filter_handler = {
|
||||
BECSignalFilter.HINTED: "include_hinted_signals",
|
||||
BECSignalFilter.NORMAL: "include_normal_signals",
|
||||
BECSignalFilter.CONFIG: "include_config_signals",
|
||||
Kind.hinted: "include_hinted_signals",
|
||||
Kind.normal: "include_normal_signals",
|
||||
Kind.config: "include_config_signals",
|
||||
}
|
||||
|
||||
def __init__(self, client=None, config=None, gui_id: str = None):
|
||||
@ -69,7 +61,7 @@ class DeviceSignalInputBase(BECWidget):
|
||||
Args:
|
||||
signal (str): signal name.
|
||||
"""
|
||||
if self.validate_signal(signal, raise_on_false=False) is True:
|
||||
if self.validate_signal(signal) is True:
|
||||
WidgetIO.set_value(widget=self, value=signal)
|
||||
self.config.default = signal
|
||||
else:
|
||||
@ -80,52 +72,61 @@ class DeviceSignalInputBase(BECWidget):
|
||||
@Slot(str)
|
||||
def set_device(self, device: str | None):
|
||||
"""
|
||||
Set the device.
|
||||
Set the device. If device is not valid, device will be set to None which happpens
|
||||
|
||||
Args:
|
||||
device(str): device name.
|
||||
"""
|
||||
if device is None:
|
||||
if self.validate_device(device) is False:
|
||||
self._device = None
|
||||
if self.validate_device(device, raise_on_false=False) is True:
|
||||
self._device = device
|
||||
self.update_signals_from_filters()
|
||||
else:
|
||||
logger.warning(f"Device {device} not found in device_manager.")
|
||||
self._device = device
|
||||
self.update_signals_from_filters()
|
||||
|
||||
@Slot()
|
||||
def update_signals_from_filters(self):
|
||||
"""Update the filters for the device signals based on list in self.signal_filter.
|
||||
In addition, store the hinted, normal and config signals in separate lists to allow
|
||||
customisation within QLineEdit."""
|
||||
customisation within QLineEdit.
|
||||
|
||||
Note:
|
||||
Signal and ComputedSignals have no signals. The naming convention follows the device name.
|
||||
"""
|
||||
self.config.signal_filter = self.signal_filter
|
||||
# pylint: disable=protected-access
|
||||
self._hinted_signals = []
|
||||
self._normal_signals = []
|
||||
self._config_signals = []
|
||||
if self._device is None:
|
||||
if self.validate_device(self._device) is False:
|
||||
self._device = None
|
||||
self.config.device = self._device
|
||||
return
|
||||
device = self.get_device_object(self._device)
|
||||
# See above convention for Signals and ComputedSignals
|
||||
if isinstance(device, Signal):
|
||||
self._signals = [self._device]
|
||||
FilterIO.set_selection(widget=self, selection=[self._device])
|
||||
return
|
||||
device_info = device._info["signals"]
|
||||
if BECSignalFilter.HINTED in self.signal_filter or len(self.signal_filter) == 0:
|
||||
if Kind.hinted in self.signal_filter:
|
||||
hinted_signals = [
|
||||
signal
|
||||
for signal, signal_info in device_info.items()
|
||||
if (signal_info.get("kind_str", None) == BECSignalFilter.HINTED)
|
||||
if (signal_info.get("kind_str", None) == str(Kind.hinted.value))
|
||||
]
|
||||
self._hinted_signals = hinted_signals
|
||||
if BECSignalFilter.NORMAL in self.signal_filter or len(self.signal_filter) == 0:
|
||||
if Kind.normal in self.signal_filter:
|
||||
normal_signals = [
|
||||
signal
|
||||
for signal, signal_info in device_info.items()
|
||||
if (signal_info.get("kind_str", None) == BECSignalFilter.NORMAL)
|
||||
if (signal_info.get("kind_str", None) == str(Kind.normal.value))
|
||||
]
|
||||
self._normal_signals = normal_signals
|
||||
if BECSignalFilter.CONFIG in self.signal_filter or len(self.signal_filter) == 0:
|
||||
if Kind.config in self.signal_filter:
|
||||
config_signals = [
|
||||
signal
|
||||
for signal, signal_info in device_info.items()
|
||||
if (signal_info.get("kind_str", None) == BECSignalFilter.CONFIG)
|
||||
if (signal_info.get("kind_str", None) == str(Kind.config.value))
|
||||
]
|
||||
self._config_signals = config_signals
|
||||
self._signals = self._hinted_signals + self._normal_signals + self._config_signals
|
||||
@ -143,8 +144,6 @@ class DeviceSignalInputBase(BECWidget):
|
||||
@device.setter
|
||||
def device(self, value: str):
|
||||
"""Set the device and update the filters, only allow devices present in the devicemanager."""
|
||||
if self.validate_device(value) is False:
|
||||
return
|
||||
self._device = value
|
||||
self.config.device = value
|
||||
self.update_signals_from_filters()
|
||||
@ -152,40 +151,40 @@ class DeviceSignalInputBase(BECWidget):
|
||||
@Property(bool)
|
||||
def include_hinted_signals(self):
|
||||
"""Include hinted signals in filters."""
|
||||
return BECSignalFilter.HINTED in self.signal_filter
|
||||
return Kind.hinted in self.signal_filter
|
||||
|
||||
@include_hinted_signals.setter
|
||||
def include_hinted_signals(self, value: bool):
|
||||
if value:
|
||||
self._signal_filter.append(BECSignalFilter.HINTED)
|
||||
self._signal_filter.append(Kind.hinted)
|
||||
else:
|
||||
self._signal_filter.remove(BECSignalFilter.HINTED)
|
||||
self._signal_filter.remove(Kind.hinted)
|
||||
self.update_signals_from_filters()
|
||||
|
||||
@Property(bool)
|
||||
def include_normal_signals(self):
|
||||
"""Include normal signals in filters."""
|
||||
return BECSignalFilter.NORMAL in self.signal_filter
|
||||
return Kind.normal in self.signal_filter
|
||||
|
||||
@include_normal_signals.setter
|
||||
def include_normal_signals(self, value: bool):
|
||||
if value:
|
||||
self._signal_filter.append(BECSignalFilter.NORMAL)
|
||||
self._signal_filter.append(Kind.normal)
|
||||
else:
|
||||
self._signal_filter.remove(BECSignalFilter.NORMAL)
|
||||
self._signal_filter.remove(Kind.normal)
|
||||
self.update_signals_from_filters()
|
||||
|
||||
@Property(bool)
|
||||
def include_config_signals(self):
|
||||
"""Include config signals in filters."""
|
||||
return BECSignalFilter.CONFIG in self.signal_filter
|
||||
return Kind.config in self.signal_filter
|
||||
|
||||
@include_config_signals.setter
|
||||
def include_config_signals(self, value: bool):
|
||||
if value:
|
||||
self._signal_filter.append(BECSignalFilter.CONFIG)
|
||||
self._signal_filter.append(Kind.config)
|
||||
else:
|
||||
self._signal_filter.remove(BECSignalFilter.CONFIG)
|
||||
self._signal_filter.remove(Kind.config)
|
||||
self.update_signals_from_filters()
|
||||
|
||||
### Properties and Methods ###
|
||||
@ -232,7 +231,7 @@ class DeviceSignalInputBase(BECWidget):
|
||||
for entry in filters:
|
||||
setattr(self, entry, True)
|
||||
|
||||
def get_device_object(self, device: str) -> object:
|
||||
def get_device_object(self, device: str) -> object | None:
|
||||
"""
|
||||
Get the device object based on the device name.
|
||||
|
||||
@ -245,10 +244,11 @@ class DeviceSignalInputBase(BECWidget):
|
||||
self.validate_device(device)
|
||||
dev = getattr(self.dev, device.lower(), None)
|
||||
if dev is None:
|
||||
raise ValueError(f"Device {device} is not found in devicemanager {self.dev}.")
|
||||
logger.warning(f"Device {device} not found in devicemanager.")
|
||||
return None
|
||||
return dev
|
||||
|
||||
def validate_device(self, device: str, raise_on_false: bool = False) -> bool:
|
||||
def validate_device(self, device: str | None, raise_on_false: bool = False) -> bool:
|
||||
"""
|
||||
Validate the device if it is present in current BEC instance.
|
||||
|
||||
@ -261,7 +261,7 @@ class DeviceSignalInputBase(BECWidget):
|
||||
raise ValueError(f"Device {device} not found in devicemanager.")
|
||||
return False
|
||||
|
||||
def validate_signal(self, signal: str, raise_on_false: bool = False) -> bool:
|
||||
def validate_signal(self, signal: str) -> bool:
|
||||
"""
|
||||
Validate the signal if it is present in the device signals.
|
||||
|
||||
@ -270,8 +270,4 @@ class DeviceSignalInputBase(BECWidget):
|
||||
"""
|
||||
if signal in self.signals:
|
||||
return True
|
||||
if raise_on_false is True:
|
||||
raise ValueError(
|
||||
f"Signal {signal} not found for device {self.device} and filtered selection {self.signal_filter}."
|
||||
)
|
||||
return False
|
||||
|
@ -36,7 +36,7 @@ class DeviceComboBox(DeviceInputBase, QComboBox):
|
||||
readout_priority_filter: (
|
||||
str | ReadoutPriority | list[str] | list[ReadoutPriority] | None
|
||||
) = None,
|
||||
device_list: list[str] | None = None,
|
||||
available_devices: list[str] | None = None,
|
||||
default: str | None = None,
|
||||
arg_name: str | None = None,
|
||||
):
|
||||
@ -49,24 +49,29 @@ class DeviceComboBox(DeviceInputBase, QComboBox):
|
||||
self.setMinimumSize(QSize(100, 0))
|
||||
self._is_valid_input = False
|
||||
self._accent_colors = get_accent_colors()
|
||||
# Set readout priority filter and device filter.
|
||||
# If value is set directly in init, this overrules value from the config
|
||||
readout_priority_filter = (
|
||||
readout_priority_filter
|
||||
if readout_priority_filter is not None
|
||||
else self.config.readout_filter
|
||||
)
|
||||
# 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.
|
||||
# Set available devices if passed
|
||||
if available_devices is not None:
|
||||
self.set_available_devices(available_devices)
|
||||
# Set readout priority filter default is all
|
||||
if readout_priority_filter is not None:
|
||||
self.set_readout_priority_filter(readout_priority_filter)
|
||||
device_filter = device_filter if device_filter is not None else self.config.device_filter
|
||||
else:
|
||||
self.set_readout_priority_filter(
|
||||
[
|
||||
ReadoutPriority.MONITORED,
|
||||
ReadoutPriority.BASELINE,
|
||||
ReadoutPriority.ASYNC,
|
||||
ReadoutPriority.CONTINUOUS,
|
||||
ReadoutPriority.ON_REQUEST,
|
||||
]
|
||||
)
|
||||
# Device filter default is None
|
||||
if device_filter is not None:
|
||||
self.set_device_filter(device_filter)
|
||||
device_list = device_list if device_list is not None else self.config.devices
|
||||
if device_list is not None:
|
||||
self.set_available_devices(device_list)
|
||||
else:
|
||||
self.update_devices_from_filters()
|
||||
default = default if default is not None else self.config.default
|
||||
# Set default device if passed
|
||||
if default is not None:
|
||||
self.set_device(default)
|
||||
|
||||
|
@ -1,7 +1,8 @@
|
||||
from bec_lib.device import ReadoutPriority
|
||||
from qtpy.QtCore import QSize
|
||||
from bec_lib.logger import bec_logger
|
||||
from qtpy.QtCore import QSize, Signal, Slot
|
||||
from qtpy.QtGui import QPainter, QPaintEvent, QPen
|
||||
from qtpy.QtWidgets import QCompleter, QLineEdit, QSizePolicy
|
||||
from qtpy.QtWidgets import QApplication, QCompleter, QLineEdit, QSizePolicy
|
||||
|
||||
from bec_widgets.utils.colors import get_accent_colors
|
||||
from bec_widgets.widgets.base_classes.device_input_base import (
|
||||
@ -10,6 +11,8 @@ from bec_widgets.widgets.base_classes.device_input_base import (
|
||||
DeviceInputConfig,
|
||||
)
|
||||
|
||||
logger = bec_logger.logger
|
||||
|
||||
|
||||
class DeviceLineEdit(DeviceInputBase, QLineEdit):
|
||||
"""
|
||||
@ -39,39 +42,46 @@ class DeviceLineEdit(DeviceInputBase, QLineEdit):
|
||||
readout_priority_filter: (
|
||||
str | ReadoutPriority | list[str] | list[ReadoutPriority] | None
|
||||
) = None,
|
||||
device_list: list[str] | None = None,
|
||||
available_devices: list[str] | None = None,
|
||||
default: str | None = None,
|
||||
arg_name: str | None = None,
|
||||
):
|
||||
self._is_valid_input = False
|
||||
self._accent_colors = get_accent_colors()
|
||||
super().__init__(client=client, config=config, gui_id=gui_id)
|
||||
QLineEdit.__init__(self, parent=parent)
|
||||
self._is_valid_input = False
|
||||
self.completer = QCompleter(self)
|
||||
self.setCompleter(self.completer)
|
||||
|
||||
if arg_name is not None:
|
||||
self.config.arg_name = arg_name
|
||||
self.arg_name = arg_name
|
||||
self.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed)
|
||||
self.setMinimumSize(QSize(100, 0))
|
||||
self._accent_colors = get_accent_colors()
|
||||
# Set readout priority filter and device filter.
|
||||
# If value is set directly in init, this overrules value from the config
|
||||
readout_priority_filter = (
|
||||
readout_priority_filter
|
||||
if readout_priority_filter is not None
|
||||
else self.config.readout_filter
|
||||
)
|
||||
|
||||
# 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.
|
||||
# Set available devices if passed
|
||||
if available_devices is not None:
|
||||
self.set_available_devices(available_devices)
|
||||
# Set readout priority filter default is all
|
||||
if readout_priority_filter is not None:
|
||||
self.set_readout_priority_filter(readout_priority_filter)
|
||||
device_filter = device_filter if device_filter is not None else self.config.device_filter
|
||||
else:
|
||||
self.set_readout_priority_filter(
|
||||
[
|
||||
ReadoutPriority.MONITORED,
|
||||
ReadoutPriority.BASELINE,
|
||||
ReadoutPriority.ASYNC,
|
||||
ReadoutPriority.CONTINUOUS,
|
||||
ReadoutPriority.ON_REQUEST,
|
||||
]
|
||||
)
|
||||
# Device filter default is None
|
||||
if device_filter is not None:
|
||||
self.set_device_filter(device_filter)
|
||||
device_list = device_list if device_list is not None else self.config.devices
|
||||
if device_list is not None:
|
||||
self.set_available_devices(device_list)
|
||||
else:
|
||||
self.update_devices_from_filters()
|
||||
default = default if default is not None else self.config.default
|
||||
# Set default device if passed
|
||||
if default is not None:
|
||||
self.set_device(default)
|
||||
self.textChanged.connect(self.check_validity)
|
||||
@ -92,16 +102,19 @@ class DeviceLineEdit(DeviceInputBase, QLineEdit):
|
||||
Args:
|
||||
event (PySide6.QtGui.QPaintEvent) : Paint event.
|
||||
"""
|
||||
# logger.info(f"Received paint event: {event} in {self.__class__}")
|
||||
super().paintEvent(event)
|
||||
painter = QPainter(self)
|
||||
pen = QPen()
|
||||
pen.setWidth(2)
|
||||
|
||||
if self._is_valid_input is False and self.isEnabled() is True:
|
||||
painter = QPainter(self)
|
||||
pen = QPen()
|
||||
pen.setWidth(2)
|
||||
pen.setColor(self._accent_colors.emergency)
|
||||
painter.setPen(pen)
|
||||
painter.drawRect(self.rect().adjusted(1, 1, -1, -1))
|
||||
painter.end()
|
||||
|
||||
@Slot(str)
|
||||
def check_validity(self, input_text: str) -> None:
|
||||
"""
|
||||
Check if the current value is a valid device name.
|
||||
@ -116,9 +129,10 @@ class DeviceLineEdit(DeviceInputBase, QLineEdit):
|
||||
|
||||
if __name__ == "__main__": # pragma: no cover
|
||||
# pylint: disable=import-outside-toplevel
|
||||
from qtpy.QtWidgets import QApplication, QVBoxLayout, QWidget
|
||||
from qtpy.QtWidgets import QVBoxLayout, QWidget
|
||||
|
||||
from bec_widgets.utils.colors import set_theme
|
||||
from bec_widgets.widgets.signal_combobox.signal_combobox import SignalComboBox
|
||||
|
||||
app = QApplication([])
|
||||
set_theme("dark")
|
||||
@ -127,7 +141,12 @@ if __name__ == "__main__": # pragma: no cover
|
||||
layout = QVBoxLayout()
|
||||
widget.setLayout(layout)
|
||||
line_edit = DeviceLineEdit()
|
||||
line_edit.include_positioner = True
|
||||
line_edit.filter_to_positioner = True
|
||||
signal_line_edit = SignalComboBox()
|
||||
line_edit.textChanged.connect(signal_line_edit.set_device)
|
||||
line_edit.set_available_devices(["samx", "samy", "samz"])
|
||||
line_edit.set_device("samx")
|
||||
layout.addWidget(line_edit)
|
||||
layout.addWidget(signal_line_edit)
|
||||
widget.show()
|
||||
app.exec_()
|
||||
|
@ -4,6 +4,7 @@ import sys
|
||||
from typing import Literal, Optional
|
||||
|
||||
import pyqtgraph as pg
|
||||
from bec_lib.device import ReadoutPriority
|
||||
from qtpy.QtWidgets import QComboBox, QVBoxLayout, QWidget
|
||||
|
||||
from bec_widgets.qt_utils.error_popups import SafeSlot, WarningPopupUtility
|
||||
@ -70,7 +71,11 @@ class BECImageWidget(BECWidget, QWidget):
|
||||
self.toolbar = ModularToolBar(
|
||||
actions={
|
||||
"monitor": DeviceSelectionAction(
|
||||
"Monitor:", DeviceComboBox(device_filter=BECDeviceFilter.DEVICE)
|
||||
"Monitor:",
|
||||
DeviceComboBox(
|
||||
device_filter=BECDeviceFilter.DEVICE,
|
||||
readout_priority_filter=[ReadoutPriority.ASYNC],
|
||||
),
|
||||
),
|
||||
"monitor_type": WidgetAction(widget=self.dim_combo_box),
|
||||
"connect": MaterialIconAction(icon_name="link", tooltip="Connect Device"),
|
||||
|
@ -21,6 +21,7 @@ from qtpy.QtWidgets import (
|
||||
)
|
||||
|
||||
from bec_widgets.utils.widget_io import WidgetIO
|
||||
from bec_widgets.widgets.base_classes.device_input_base import BECDeviceFilter
|
||||
from bec_widgets.widgets.device_line_edit.device_line_edit import DeviceLineEdit
|
||||
|
||||
logger = bec_logger.logger
|
||||
@ -233,6 +234,7 @@ class ScanGroupBox(QGroupBox):
|
||||
default = None
|
||||
widget = widget_class(arg_name=arg_name, default=default)
|
||||
if isinstance(widget, DeviceLineEdit):
|
||||
widget.set_device_filter(BECDeviceFilter.DEVICE)
|
||||
self.selected_devices[widget] = ""
|
||||
widget.device_selected.connect(self.emit_device_selected)
|
||||
tooltip = item.get("tooltip", None)
|
||||
|
@ -1,4 +1,6 @@
|
||||
from qtpy.QtCore import QSize
|
||||
from bec_lib.device import Positioner
|
||||
from ophyd import Kind
|
||||
from qtpy.QtCore import QSize, Signal, Slot
|
||||
from qtpy.QtWidgets import QComboBox, QSizePolicy
|
||||
|
||||
from bec_widgets.utils.filter_io import ComboBoxFilterHandler, FilterIO
|
||||
@ -21,6 +23,8 @@ class SignalComboBox(DeviceSignalInputBase, QComboBox):
|
||||
|
||||
ICON_NAME = "list_alt"
|
||||
|
||||
device_signal_changed = Signal(str)
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
parent=None,
|
||||
@ -42,13 +46,16 @@ class SignalComboBox(DeviceSignalInputBase, QComboBox):
|
||||
|
||||
self.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed)
|
||||
self.setMinimumSize(QSize(100, 0))
|
||||
signal_filter = signal_filter if not None else self.config.signal_filter
|
||||
# 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.
|
||||
self.currentTextChanged.connect(self.on_text_changed)
|
||||
if signal_filter is not None:
|
||||
self.set_filter(signal_filter)
|
||||
device = device if not None else self.config.device
|
||||
else:
|
||||
self.set_filter([Kind.hinted, Kind.normal, Kind.config])
|
||||
if device is not None:
|
||||
self.set_device(device)
|
||||
default = default if not None else self.config.default
|
||||
if default is not None:
|
||||
self.set_signal(default)
|
||||
|
||||
@ -71,6 +78,24 @@ class SignalComboBox(DeviceSignalInputBase, QComboBox):
|
||||
self.insertItem(0, "Hinted Signals")
|
||||
self.model().item(0).setEnabled(False)
|
||||
|
||||
@Slot(str)
|
||||
def on_text_changed(self, text: str):
|
||||
"""Slot for text changed. If a device is selected and the signal is changed and valid it emits a signal.
|
||||
For a positioner, the readback value has to be renamed to the device name.
|
||||
|
||||
Args:
|
||||
text (str): Text in the combobox.
|
||||
"""
|
||||
if self.validate_device(self.device) is False:
|
||||
return
|
||||
if self.validate_signal(text) is False:
|
||||
return
|
||||
if text == "readback" and isinstance(self.get_device_object(self.device), Positioner):
|
||||
device_signal = self.device
|
||||
else:
|
||||
device_signal = f"{self.device}_{text}"
|
||||
self.device_signal_changed.emit(device_signal)
|
||||
|
||||
|
||||
if __name__ == "__main__": # pragma: no cover
|
||||
# pylint: disable=import-outside-toplevel
|
||||
|
@ -1,4 +1,5 @@
|
||||
from qtpy.QtCore import QSize, Slot
|
||||
from ophyd import Kind
|
||||
from qtpy.QtCore import QSize, Signal, Slot
|
||||
from qtpy.QtGui import QPainter, QPaintEvent, QPen
|
||||
from qtpy.QtWidgets import QCompleter, QLineEdit, QSizePolicy
|
||||
|
||||
@ -20,6 +21,8 @@ class SignalLineEdit(DeviceSignalInputBase, QLineEdit):
|
||||
arg_name: Argument name, can be used for the other widgets which has to call some other function in bec using correct argument names.
|
||||
"""
|
||||
|
||||
device_signal_changed = Signal(str)
|
||||
|
||||
ICON_NAME = "vital_signs"
|
||||
|
||||
def __init__(
|
||||
@ -33,9 +36,9 @@ class SignalLineEdit(DeviceSignalInputBase, QLineEdit):
|
||||
default: str | None = None,
|
||||
arg_name: str | None = None,
|
||||
):
|
||||
self._is_valid_input = False
|
||||
super().__init__(client=client, config=config, gui_id=gui_id)
|
||||
QLineEdit.__init__(self, parent=parent)
|
||||
self._is_valid_input = False
|
||||
self._accent_colors = get_accent_colors()
|
||||
self.completer = QCompleter(self)
|
||||
self.setCompleter(self.completer)
|
||||
@ -47,13 +50,15 @@ class SignalLineEdit(DeviceSignalInputBase, QLineEdit):
|
||||
|
||||
self.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed)
|
||||
self.setMinimumSize(QSize(100, 0))
|
||||
signal_filter = signal_filter if not None else self.config.signal_filter
|
||||
# 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.
|
||||
if signal_filter is not None:
|
||||
self.set_filter(signal_filter)
|
||||
device = device if not None else self.config.device
|
||||
else:
|
||||
self.set_filter([Kind.hinted, Kind.normal, Kind.config])
|
||||
if device is not None:
|
||||
self.set_device(device)
|
||||
default = default if not None else self.config.default
|
||||
if default is not None:
|
||||
self.set_signal(default)
|
||||
self.textChanged.connect(self.check_validity)
|
||||
@ -89,9 +94,10 @@ class SignalLineEdit(DeviceSignalInputBase, QLineEdit):
|
||||
"""
|
||||
Check if the current value is a valid device name.
|
||||
"""
|
||||
# i
|
||||
if self.validate_signal(input_text) is True:
|
||||
self._is_valid_input = True
|
||||
if self.validate_device(self.device) is True:
|
||||
self.device_signal_changed.emit(input_text)
|
||||
else:
|
||||
self._is_valid_input = False
|
||||
self.update()
|
||||
|
@ -36,7 +36,7 @@ def test_device_input_base_init(device_input_base):
|
||||
assert device_input_base.client is not None
|
||||
assert isinstance(device_input_base, DeviceInputBase)
|
||||
assert device_input_base.config.widget_class == "DeviceInputWidget"
|
||||
assert device_input_base.config.device_filter is None
|
||||
assert device_input_base.config.device_filter == []
|
||||
assert device_input_base.config.default is None
|
||||
assert device_input_base.devices == []
|
||||
|
||||
@ -62,17 +62,15 @@ def test_device_input_base_set_device_filter(device_input_base):
|
||||
|
||||
|
||||
def test_device_input_base_set_device_filter_error(device_input_base):
|
||||
"""Test set_device_filter with Noneexisting class"""
|
||||
with pytest.raises(ValueError) as excinfo:
|
||||
device_input_base.set_device_filter("NonExistingClass")
|
||||
assert "Device filter NonExistingClass is not in the device list." in str(excinfo.value)
|
||||
"""Test set_device_filter with Noneexisting class. This should not raise. It writes a log message entry."""
|
||||
device_input_base.set_device_filter("NonExistingClass")
|
||||
assert device_input_base.device_filter == []
|
||||
|
||||
|
||||
def test_device_input_base_set_default_device(device_input_base):
|
||||
"""Test setting the default device. Also tests the update_devices method."""
|
||||
with pytest.raises(ValueError) as excinfo:
|
||||
device_input_base.set_device("samx")
|
||||
assert "Device samx is not in filtered selection." in str(excinfo.value)
|
||||
device_input_base.set_device("samx")
|
||||
assert device_input_base.config.default == None
|
||||
device_input_base.set_device_filter(BECDeviceFilter.POSITIONER)
|
||||
device_input_base.set_readout_priority_filter(ReadoutPriority.MONITORED)
|
||||
device_input_base.set_device("samx")
|
||||
@ -99,17 +97,17 @@ def test_device_input_base_get_filters(device_input_base):
|
||||
def test_device_input_base_properties(device_input_base):
|
||||
"""Test setting the properties of the device input base."""
|
||||
assert device_input_base.device_filter == []
|
||||
device_input_base.include_device = True
|
||||
device_input_base.filter_to_device = True
|
||||
assert device_input_base.device_filter == [BECDeviceFilter.DEVICE]
|
||||
device_input_base.include_positioner = True
|
||||
device_input_base.filter_to_positioner = True
|
||||
assert device_input_base.device_filter == [BECDeviceFilter.DEVICE, BECDeviceFilter.POSITIONER]
|
||||
device_input_base.include_computed_signal = True
|
||||
device_input_base.filter_to_computed_signal = True
|
||||
assert device_input_base.device_filter == [
|
||||
BECDeviceFilter.DEVICE,
|
||||
BECDeviceFilter.POSITIONER,
|
||||
BECDeviceFilter.COMPUTED_SIGNAL,
|
||||
]
|
||||
device_input_base.include_signal = True
|
||||
device_input_base.filter_to_signal = True
|
||||
assert device_input_base.device_filter == [
|
||||
BECDeviceFilter.DEVICE,
|
||||
BECDeviceFilter.POSITIONER,
|
||||
|
@ -16,21 +16,6 @@ def device_input_combobox(qtbot, mocked_client):
|
||||
yield widget
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def device_input_combobox_with_config(qtbot, mocked_client):
|
||||
config = {
|
||||
"widget_class": "DeviceComboBox",
|
||||
"gui_id": "test_gui_id",
|
||||
"device_filter": [BECDeviceFilter.POSITIONER],
|
||||
"default": "samx",
|
||||
"arg_name": "test_arg_name",
|
||||
}
|
||||
widget = DeviceComboBox(client=mocked_client, config=config)
|
||||
qtbot.addWidget(widget)
|
||||
qtbot.waitExposed(widget)
|
||||
yield widget
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def device_input_combobox_with_kwargs(qtbot, mocked_client):
|
||||
widget = DeviceComboBox(
|
||||
@ -72,13 +57,6 @@ def test_device_input_combobox_init(device_input_combobox):
|
||||
]
|
||||
|
||||
|
||||
def test_device_input_combobox_init_with_config(device_input_combobox_with_config):
|
||||
assert device_input_combobox_with_config.config.gui_id == "test_gui_id"
|
||||
assert device_input_combobox_with_config.config.device_filter == [BECDeviceFilter.POSITIONER]
|
||||
assert device_input_combobox_with_config.config.default == "samx"
|
||||
assert device_input_combobox_with_config.config.arg_name == "test_arg_name"
|
||||
|
||||
|
||||
def test_device_input_combobox_init_with_kwargs(device_input_combobox_with_kwargs):
|
||||
assert device_input_combobox_with_kwargs.config.gui_id == "test_gui_id"
|
||||
assert device_input_combobox_with_kwargs.config.device_filter == [BECDeviceFilter.POSITIONER]
|
||||
@ -102,21 +80,6 @@ def device_input_line_edit(qtbot, mocked_client):
|
||||
yield widget
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def device_input_line_edit_with_config(qtbot, mocked_client):
|
||||
config = {
|
||||
"widget_class": "DeviceLineEdit",
|
||||
"gui_id": "test_gui_id",
|
||||
"device_filter": [BECDeviceFilter.POSITIONER],
|
||||
"default": "samx",
|
||||
"arg_name": "test_arg_name",
|
||||
}
|
||||
widget = DeviceLineEdit(client=mocked_client, config=config)
|
||||
qtbot.addWidget(widget)
|
||||
qtbot.waitExposed(widget)
|
||||
yield widget
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def device_input_line_edit_with_kwargs(qtbot, mocked_client):
|
||||
widget = DeviceLineEdit(
|
||||
@ -137,7 +100,13 @@ def test_device_input_line_edit_init(device_input_line_edit):
|
||||
assert isinstance(device_input_line_edit, DeviceLineEdit)
|
||||
assert device_input_line_edit.config.widget_class == "DeviceLineEdit"
|
||||
assert device_input_line_edit.config.device_filter == []
|
||||
assert device_input_line_edit.config.readout_filter == []
|
||||
assert device_input_line_edit.config.readout_filter == [
|
||||
ReadoutPriority.MONITORED,
|
||||
ReadoutPriority.BASELINE,
|
||||
ReadoutPriority.ASYNC,
|
||||
ReadoutPriority.CONTINUOUS,
|
||||
ReadoutPriority.ON_REQUEST,
|
||||
]
|
||||
assert device_input_line_edit.config.default is None
|
||||
assert device_input_line_edit.devices == [
|
||||
"samx",
|
||||
@ -160,13 +129,6 @@ def test_device_input_line_edit_init(device_input_line_edit):
|
||||
]
|
||||
|
||||
|
||||
def test_device_input_line_edit_init_with_config(device_input_line_edit_with_config):
|
||||
assert device_input_line_edit_with_config.config.gui_id == "test_gui_id"
|
||||
assert device_input_line_edit_with_config.config.device_filter == [BECDeviceFilter.POSITIONER]
|
||||
assert device_input_line_edit_with_config.config.default == "samx"
|
||||
assert device_input_line_edit_with_config.config.arg_name == "test_arg_name"
|
||||
|
||||
|
||||
def test_device_input_line_edit_init_with_kwargs(device_input_line_edit_with_kwargs):
|
||||
assert device_input_line_edit_with_kwargs.config.gui_id == "test_gui_id"
|
||||
assert device_input_line_edit_with_kwargs.config.device_filter == [BECDeviceFilter.POSITIONER]
|
||||
|
@ -1,12 +1,12 @@
|
||||
from unittest import mock
|
||||
|
||||
import pytest
|
||||
from ophyd import Kind
|
||||
from qtpy.QtWidgets import QWidget
|
||||
|
||||
from bec_widgets.widgets.base_classes.device_signal_input_base import (
|
||||
BECSignalFilter,
|
||||
DeviceSignalInputBase,
|
||||
)
|
||||
from bec_widgets.widgets.base_classes.device_input_base import BECDeviceFilter
|
||||
from bec_widgets.widgets.base_classes.device_signal_input_base import DeviceSignalInputBase
|
||||
from bec_widgets.widgets.device_combobox.device_combobox import DeviceComboBox
|
||||
from bec_widgets.widgets.signal_combobox.signal_combobox import SignalComboBox
|
||||
from bec_widgets.widgets.signal_line_edit.signal_line_edit import SignalLineEdit
|
||||
|
||||
@ -45,6 +45,19 @@ def device_signal_line_edit(qtbot, mocked_client):
|
||||
yield widget
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def test_device_signal_combo(qtbot, mocked_client):
|
||||
"""Fixture to create a SignalComboBox widget and a DeviceInputWidget widget"""
|
||||
input = create_widget(
|
||||
qtbot=qtbot,
|
||||
widget=DeviceComboBox,
|
||||
client=mocked_client,
|
||||
device_filter=[BECDeviceFilter.POSITIONER],
|
||||
)
|
||||
signal = create_widget(qtbot=qtbot, widget=SignalComboBox, client=mocked_client)
|
||||
yield input, signal
|
||||
|
||||
|
||||
def test_device_signal_base_init(device_signal_base):
|
||||
"""Test if the DeviceSignalInputBase is initialized correctly"""
|
||||
assert device_signal_base._device is None
|
||||
@ -58,15 +71,11 @@ def test_device_signal_base_init(device_signal_base):
|
||||
def test_device_signal_qproperties(device_signal_base):
|
||||
"""Test if the DeviceSignalInputBase has the correct QProperties"""
|
||||
device_signal_base.include_config_signals = True
|
||||
assert device_signal_base._signal_filter == [BECSignalFilter.CONFIG]
|
||||
assert device_signal_base._signal_filter == [Kind.config]
|
||||
device_signal_base.include_normal_signals = True
|
||||
assert device_signal_base._signal_filter == [BECSignalFilter.CONFIG, BECSignalFilter.NORMAL]
|
||||
assert device_signal_base._signal_filter == [Kind.config, Kind.normal]
|
||||
device_signal_base.include_hinted_signals = True
|
||||
assert device_signal_base._signal_filter == [
|
||||
BECSignalFilter.CONFIG,
|
||||
BECSignalFilter.NORMAL,
|
||||
BECSignalFilter.HINTED,
|
||||
]
|
||||
assert device_signal_base._signal_filter == [Kind.config, Kind.normal, Kind.hinted]
|
||||
|
||||
|
||||
def test_device_signal_set_device(device_signal_base):
|
||||
|
Reference in New Issue
Block a user