0
0
mirror of https://github.com/bec-project/bec_widgets.git synced 2025-07-14 11:41:49 +02:00

feat(device_combobox): DeviceInputBase and DeviceComboBox added

This commit is contained in:
2024-06-18 11:53:28 +02:00
committed by wyzula_j
parent 17133771bb
commit 430b282039
4 changed files with 219 additions and 0 deletions

View File

@ -0,0 +1 @@
from .device_combobox.device_combobox import DeviceComboBox

View File

@ -0,0 +1,88 @@
from typing import TYPE_CHECKING
from qtpy.QtWidgets import QComboBox
from bec_widgets.widgets.device_inputs.device_input_base import DeviceInputBase, DeviceInputConfig
if TYPE_CHECKING:
from bec_widgets.widgets.device_inputs.device_input_base import DeviceInputConfig
class DeviceComboBox(DeviceInputBase, QComboBox):
def __init__(
self,
parent=None,
client=None,
config: DeviceInputConfig = None,
gui_id: str | None = None,
device_filter: str = None,
default_device: str = None,
):
super().__init__(
client=client,
config=config,
gui_id=gui_id,
device_filter=device_filter,
default_device=default_device,
)
QComboBox.__init__(self, parent=parent)
self.populate_combobox()
self._set_defaults()
def _set_defaults(self):
"""Set the default device and device filter."""
if self.config.default_device is not None:
self.set_default_device(self.config.default_device)
if self.config.device_filter is not None:
self.set_device_filter(self.config.device_filter)
def set_device_filter(self, device_filter: str):
"""
Set the device filter.
Args:
device_filter(str): Device filter, name of the device class.
"""
super().set_device_filter(device_filter)
self.populate_combobox()
def set_default_device(self, default_device: str):
"""
Set the default device.
Args:
default_device(str): Default device name.
"""
super().set_default_device(default_device)
self.setCurrentText(default_device)
def populate_combobox(self):
"""Populate the combobox with the devices."""
self.devices = self.get_device_list(self.config.device_filter)
self.clear()
self.addItems(self.devices)
def get_device(self) -> object:
"""
Get the selected device object.
Returns:
object: Device object.
"""
device_name = self.currentText()
device_obj = getattr(self.dev, device_name.lower(), None)
if device_obj is None:
raise ValueError(f"Device {device_name} is not found.")
return device_obj
if __name__ == "__main__": # pragma: no cover
import sys
from qtpy.QtWidgets import QApplication
app = QApplication(sys.argv)
w = DeviceComboBox(default_device="samx")
w.show()
sys.exit(app.exec_())

View File

@ -0,0 +1,130 @@
from __future__ import annotations
from bec_widgets.utils import BECConnector, ConnectionConfig
class DeviceInputConfig(ConnectionConfig):
device_filter: str | list[str] | None = None
default_device: str | None = None
class DeviceInputBase(BECConnector):
"""
Mixin class for device input widgets. This class provides methods to get the device list and device object based
on the current text of the widget.
"""
def __init__(
self,
parent=None,
client=None,
config=None,
gui_id=None,
device_filter: str = None,
default_device: str = None,
):
if config is None:
config = DeviceInputConfig(widget_class=self.__class__.__name__)
else:
if isinstance(config, dict):
config = DeviceInputConfig(**config)
self.config = config
super().__init__(client=client, config=config, gui_id=gui_id)
self.get_bec_shortcuts()
self.config.device_filter = device_filter
self.config.default_device = default_device
self._devices = []
@property
def devices(self) -> list[str]:
"""
Get the list of devices.
Returns:
list[str]: List of devices.
"""
return self._devices
@devices.setter
def devices(self, value: list[str]):
"""
Set the list of devices.
Args:
value: List of devices.
"""
self._devices = value
def set_device_filter(self, device_filter: str | list[str]):
"""
Set the device filter.
Args:
device_filter(str): Device filter, name of the device class.
"""
self.validate_device_filter(device_filter)
self.config.device_filter = device_filter
def set_default_device(self, default_device: str):
"""
Set the default device.
Args:
default_device(str): Default device name.
"""
if default_device not in self.get_device_list(self.config.device_filter):
raise ValueError(f"Default device {default_device} is not in the device list.")
self.config.default_device = default_device
def get_device_list(self, filter: str | list[str] | None = None) -> list[str]:
"""
Get the list of device names based on the filter of current BEC client.
Args:
filter(str|None): Class name filter to apply on the device list.
Returns:
devices(list[str]): List of device names.
"""
all_devices = self.dev.enabled_devices
if filter is not None:
self.validate_device_filter(filter)
if isinstance(filter, str):
filter = [filter]
devices = [device.name for device in all_devices if device.__class__.__name__ in filter]
else:
devices = [device.name for device in all_devices]
return devices
def get_available_filters(self):
"""
Get the available device classes which can be used as filters.
"""
all_devices = self.dev.enabled_devices
filters = {device.__class__.__name__ for device in all_devices}
return filters
def validate_device_filter(self, filter: str | list[str]) -> None:
"""
Validate the device filter if the class name is present in the current BEC instance.
Args:
filter(str|list[str]): Class name to use as a device filter.
"""
if isinstance(filter, str):
filter = [filter]
available_filters = self.get_available_filters()
for f in filter:
if f not in available_filters:
raise ValueError(f"Device filter {f} is not valid.")
def validate_device(self, device: str) -> None:
"""
Validate the device if it is present in current BEC instance.
Args:
device(str): Device to validate.
"""
if device not in self.get_device_list():
raise ValueError(f"Device {device} is not valid.")