0
0
mirror of https://github.com/bec-project/bec_widgets.git synced 2025-07-14 03:31:50 +02:00

refactor: do not flush selection upon receiving config update; allow widgetIO to receive kwargs to be able to use get_value to receive string instead of int for QComboBox

This commit is contained in:
2024-10-24 14:01:18 +02:00
parent 5eb15b785f
commit 91959e82de
12 changed files with 168 additions and 50 deletions

View File

@ -1,11 +1,9 @@
from unittest.mock import MagicMock from unittest.mock import MagicMock
from bec_lib.client import BECClient
from bec_lib.device import Device as BECDevice from bec_lib.device import Device as BECDevice
from bec_lib.device import Positioner as BECPositioner from bec_lib.device import Positioner as BECPositioner
from bec_lib.device import ReadoutPriority from bec_lib.device import ReadoutPriority
from bec_lib.devicemanager import DeviceContainer from bec_lib.devicemanager import DeviceContainer
from bec_lib.redis_connector import RedisConnector
class FakeDevice(BECDevice): class FakeDevice(BECDevice):
@ -80,6 +78,8 @@ class FakePositioner(BECPositioner):
super().__init__(name=name) super().__init__(name=name)
# self.limits = limits if limits is not None else [0.0, 0.0] # self.limits = limits if limits is not None else [0.0, 0.0]
self.read_value = read_value self.read_value = read_value
self.setpoint_value = read_value
self.motor_is_moving_value = 0
self._enabled = enabled self._enabled = enabled
self._limits = limits self._limits = limits
self._readout_priority = readout_priority self._readout_priority = readout_priority
@ -101,6 +101,11 @@ class FakePositioner(BECPositioner):
"velocity": {"kind_str": "2"}, # config "velocity": {"kind_str": "2"}, # config
} }
} }
self.signals = {
self.name: {"value": self.read_value},
f"{self.name}_setpoint": {"value": self.setpoint_value},
f"{self.name}_motor_is_moving": {"value": self.motor_is_moving_value},
}
@property @property
def readout_priority(self): def readout_priority(self):
@ -139,7 +144,7 @@ class FakePositioner(BECPositioner):
Args: Args:
fake_value(float): Desired fake value fake_value(float): Desired fake value
""" """
self.signals[self.name]["value"] = fake_value self.read_value = fake_value
def describe(self) -> dict: def describe(self) -> dict:
""" """
@ -157,11 +162,7 @@ class FakePositioner(BECPositioner):
self.read_value = value self.read_value = value
def read(self): def read(self):
return { return self.signals
self.name: {"value": self.read_value},
f"{self.name}_setpoint": {"value": self.read_value},
f"{self.name}_motor_is_moving": {"value": 0},
}
def set_limits(self, limits): def set_limits(self, limits):
self.limits = limits self.limits = limits

View File

@ -1,5 +1,6 @@
# pylint: disable=no-name-in-module # pylint: disable=no-name-in-module
from abc import ABC, abstractmethod from abc import ABC, abstractmethod
from typing import Literal
from qtpy.QtWidgets import ( from qtpy.QtWidgets import (
QApplication, QApplication,
@ -20,7 +21,7 @@ class WidgetHandler(ABC):
"""Abstract base class for all widget handlers.""" """Abstract base class for all widget handlers."""
@abstractmethod @abstractmethod
def get_value(self, widget: QWidget): def get_value(self, widget: QWidget, **kwargs):
"""Retrieve value from the widget instance.""" """Retrieve value from the widget instance."""
@abstractmethod @abstractmethod
@ -31,7 +32,7 @@ class WidgetHandler(ABC):
class LineEditHandler(WidgetHandler): class LineEditHandler(WidgetHandler):
"""Handler for QLineEdit widgets.""" """Handler for QLineEdit widgets."""
def get_value(self, widget: QLineEdit) -> str: def get_value(self, widget: QLineEdit, **kwargs) -> str:
return widget.text() return widget.text()
def set_value(self, widget: QLineEdit, value: str) -> None: def set_value(self, widget: QLineEdit, value: str) -> None:
@ -41,7 +42,9 @@ class LineEditHandler(WidgetHandler):
class ComboBoxHandler(WidgetHandler): class ComboBoxHandler(WidgetHandler):
"""Handler for QComboBox widgets.""" """Handler for QComboBox widgets."""
def get_value(self, widget: QComboBox) -> int: def get_value(self, widget: QComboBox, as_string: bool = False, **kwargs) -> int | str:
if as_string is True:
return widget.currentText()
return widget.currentIndex() return widget.currentIndex()
def set_value(self, widget: QComboBox, value: int | str) -> None: def set_value(self, widget: QComboBox, value: int | str) -> None:
@ -54,7 +57,7 @@ class ComboBoxHandler(WidgetHandler):
class TableWidgetHandler(WidgetHandler): class TableWidgetHandler(WidgetHandler):
"""Handler for QTableWidget widgets.""" """Handler for QTableWidget widgets."""
def get_value(self, widget: QTableWidget) -> list: def get_value(self, widget: QTableWidget, **kwargs) -> list:
return [ return [
[ [
widget.item(row, col).text() if widget.item(row, col) else "" widget.item(row, col).text() if widget.item(row, col) else ""
@ -73,7 +76,7 @@ class TableWidgetHandler(WidgetHandler):
class SpinBoxHandler(WidgetHandler): class SpinBoxHandler(WidgetHandler):
"""Handler for QSpinBox and QDoubleSpinBox widgets.""" """Handler for QSpinBox and QDoubleSpinBox widgets."""
def get_value(self, widget): def get_value(self, widget, **kwargs):
return widget.value() return widget.value()
def set_value(self, widget, value): def set_value(self, widget, value):
@ -83,7 +86,7 @@ class SpinBoxHandler(WidgetHandler):
class CheckBoxHandler(WidgetHandler): class CheckBoxHandler(WidgetHandler):
"""Handler for QCheckBox widgets.""" """Handler for QCheckBox widgets."""
def get_value(self, widget): def get_value(self, widget, **kwargs):
return widget.isChecked() return widget.isChecked()
def set_value(self, widget, value): def set_value(self, widget, value):
@ -93,7 +96,7 @@ class CheckBoxHandler(WidgetHandler):
class LabelHandler(WidgetHandler): class LabelHandler(WidgetHandler):
"""Handler for QLabel widgets.""" """Handler for QLabel widgets."""
def get_value(self, widget): def get_value(self, widget, **kwargs):
return widget.text() return widget.text()
def set_value(self, widget, value): def set_value(self, widget, value):
@ -114,7 +117,7 @@ class WidgetIO:
} }
@staticmethod @staticmethod
def get_value(widget, ignore_errors=False): def get_value(widget, ignore_errors=False, **kwargs):
""" """
Retrieve value from the widget instance. Retrieve value from the widget instance.
@ -124,7 +127,7 @@ class WidgetIO:
""" """
handler_class = WidgetIO._find_handler(widget) handler_class = WidgetIO._find_handler(widget)
if handler_class: if handler_class:
return handler_class().get_value(widget) # Instantiate the handler return handler_class().get_value(widget, **kwargs) # Instantiate the handler
if not ignore_errors: if not ignore_errors:
raise ValueError(f"No handler for widget type: {type(widget)}") raise ValueError(f"No handler for widget type: {type(widget)}")
return None return None

View File

@ -2,10 +2,10 @@ from __future__ import annotations
import enum import enum
from bec_lib.callback_handler import EventType from bec_lib.device import ComputedSignal, Device, Positioner, ReadoutPriority
from bec_lib.device import ComputedSignal, Device, Positioner, ReadoutPriority, Signal from bec_lib.device import Signal as BECSignal
from bec_lib.logger import bec_logger from bec_lib.logger import bec_logger
from qtpy.QtCore import Property, Slot from qtpy.QtCore import Property, Signal, Slot
from bec_widgets.utils import ConnectionConfig from bec_widgets.utils import ConnectionConfig
from bec_widgets.utils.bec_widget import BECWidget from bec_widgets.utils.bec_widget import BECWidget
@ -43,7 +43,7 @@ class DeviceInputBase(BECWidget):
_device_handler = { _device_handler = {
BECDeviceFilter.DEVICE: Device, BECDeviceFilter.DEVICE: Device,
BECDeviceFilter.POSITIONER: Positioner, BECDeviceFilter.POSITIONER: Positioner,
BECDeviceFilter.SIGNAL: Signal, BECDeviceFilter.SIGNAL: BECSignal,
BECDeviceFilter.COMPUTED_SIGNAL: ComputedSignal, BECDeviceFilter.COMPUTED_SIGNAL: ComputedSignal,
} }
@ -72,9 +72,6 @@ class DeviceInputBase(BECWidget):
self._device_filter = [] self._device_filter = []
self._readout_filter = [] self._readout_filter = []
self._devices = [] self._devices = []
self.bec_dispatcher.client.callbacks.register(
EventType.DEVICE_UPDATE, self.update_devices_from_filters
)
### QtSlots ### ### QtSlots ###
@ -92,15 +89,13 @@ class DeviceInputBase(BECWidget):
else: else:
logger.warning(f"Device {device} is not in the filtered selection.") logger.warning(f"Device {device} is not in the filtered selection.")
@Slot(dict, dict)
@Slot() @Slot()
def update_devices_from_filters( def update_devices_from_filters(self):
self, content: dict | None = None, metadata: dict | None = None
):
"""Update the devices based on the current filter selection """Update the devices based on the current filter selection
in self.device_filter and self.readout_filter. If apply_filter is False, 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. it will not apply the filters, store the filter settings and return.
""" """
current_device = WidgetIO.get_value(widget=self, as_string=True)
self.config.device_filter = self.device_filter self.config.device_filter = self.device_filter
self.config.readout_filter = self.readout_filter self.config.readout_filter = self.readout_filter
if self.apply_filter is False: if self.apply_filter is False:
@ -111,6 +106,7 @@ class DeviceInputBase(BECWidget):
# Filter based on readout priority # Filter based on readout priority
devs = [dev for dev in devs if self._check_readout_filter(dev)] devs = [dev for dev in devs if self._check_readout_filter(dev)]
self.devices = [device.name for device in devs] self.devices = [device.name for device in devs]
self.set_device(current_device)
@Slot(list) @Slot(list)
def set_available_devices(self, devices: list[str]): def set_available_devices(self, devices: list[str]):
@ -153,6 +149,8 @@ class DeviceInputBase(BECWidget):
def default(self, value: str): def default(self, value: str):
if self.validate_device(value) is False: if self.validate_device(value) is False:
return return
self.config.default = value
WidgetIO.set_value(widget=self, value=value)
@Property(bool) @Property(bool)
def apply_filter(self): def apply_filter(self):
@ -343,7 +341,9 @@ class DeviceInputBase(BECWidget):
for entry in filters: for entry in filters:
setattr(self, entry, True) setattr(self, entry, True)
def _check_device_filter(self, device: Device | Signal | ComputedSignal | Positioner) -> bool: def _check_device_filter(
self, device: Device | BECSignal | ComputedSignal | Positioner
) -> bool:
"""Check if filter for device type is applied or not. """Check if filter for device type is applied or not.
Args: Args:
@ -351,7 +351,9 @@ class DeviceInputBase(BECWidget):
""" """
return all(isinstance(device, self._device_handler[entry]) for entry in self.device_filter) 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: def _check_readout_filter(
self, device: Device | BECSignal | ComputedSignal | Positioner
) -> bool:
"""Check if filter for readout priority is applied or not. """Check if filter for readout priority is applied or not.
Args: Args:
@ -373,7 +375,7 @@ class DeviceInputBase(BECWidget):
dev = getattr(self.dev, device.lower(), None) dev = getattr(self.dev, device.lower(), None)
if dev is None: if dev is None:
raise ValueError( raise ValueError(
f"Device {device} is not found in devicemanager {self.dev} as enabled device." f"Device {device} is not found in the device manager {self.dev} as enabled device."
) )
return dev return dev
@ -384,6 +386,7 @@ class DeviceInputBase(BECWidget):
Args: Args:
device(str): Device to validate. device(str): Device to validate.
""" """
if device in self.devices: all_devs = [dev.name for dev in self.dev.enabled_devices]
if device in self.devices and device in all_devs:
return True return True
return False return False

View File

@ -1,5 +1,7 @@
from bec_lib.callback_handler import EventType
from bec_lib.device import ReadoutPriority from bec_lib.device import ReadoutPriority
from qtpy.QtCore import QSize from qtpy.QtCore import QSize, Signal, Slot
from qtpy.QtGui import QPainter, QPaintEvent, QPen
from qtpy.QtWidgets import QComboBox, QSizePolicy from qtpy.QtWidgets import QComboBox, QSizePolicy
from bec_widgets.utils.colors import get_accent_colors from bec_widgets.utils.colors import get_accent_colors
@ -26,6 +28,9 @@ class DeviceComboBox(DeviceInputBase, QComboBox):
ICON_NAME = "list_alt" ICON_NAME = "list_alt"
device_selected = Signal(str)
device_config_update = Signal()
def __init__( def __init__(
self, self,
parent=None, parent=None,
@ -47,6 +52,7 @@ class DeviceComboBox(DeviceInputBase, QComboBox):
self.arg_name = arg_name self.arg_name = arg_name
self.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed) self.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed)
self.setMinimumSize(QSize(100, 0)) self.setMinimumSize(QSize(100, 0))
self._callback_id = None
self._is_valid_input = False self._is_valid_input = False
self._accent_colors = get_accent_colors() self._accent_colors = get_accent_colors()
# We do not consider the config that is passed here, this produced problems # We do not consider the config that is passed here, this produced problems
@ -74,6 +80,28 @@ class DeviceComboBox(DeviceInputBase, QComboBox):
# Set default device if passed # Set default device if passed
if default is not None: if default is not None:
self.set_device(default) self.set_device(default)
self._callback_id = self.bec_dispatcher.client.callbacks.register(
EventType.DEVICE_UPDATE, self.on_device_update
)
self.device_config_update.connect(self.update_devices_from_filters)
self.currentTextChanged.connect(self.check_validity)
self.check_validity(self.currentText())
def on_device_update(self, action: str, content: dict) -> None:
"""
Callback for device update events. Triggers the device_update signal.
Args:
action (str): The action that triggered the event.
content (dict): The content of the config update.
"""
if action in ["add", "remove", "reload"]:
self.device_config_update.emit()
def cleanup(self):
"""Cleanup the widget."""
if self._callback_id is not None:
self.bec_dispatcher.client.callbacks.remove(self._callback_id)
def get_current_device(self) -> object: def get_current_device(self) -> object:
""" """
@ -85,6 +113,36 @@ class DeviceComboBox(DeviceInputBase, QComboBox):
dev_name = self.currentText() dev_name = self.currentText()
return self.get_device_object(dev_name) return self.get_device_object(dev_name)
def paintEvent(self, event: QPaintEvent) -> None:
"""Extend the paint event to set the border color based on the validity of the input.
Args:
event (PySide6.QtGui.QPaintEvent) : Paint event.
"""
# logger.info(f"Received paint event: {event} in {self.__class__}")
super().paintEvent(event)
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.
"""
if self.validate_device(input_text) is True:
self._is_valid_input = True
self.device_selected.emit(input_text.lower())
else:
self._is_valid_input = False
self.update()
if __name__ == "__main__": # pragma: no cover if __name__ == "__main__": # pragma: no cover
# pylint: disable=import-outside-toplevel # pylint: disable=import-outside-toplevel
@ -99,6 +157,7 @@ if __name__ == "__main__": # pragma: no cover
layout = QVBoxLayout() layout = QVBoxLayout()
widget.setLayout(layout) widget.setLayout(layout)
combo = DeviceComboBox() combo = DeviceComboBox()
combo.devices = ["samx", "dev1", "dev2", "dev3", "dev4"]
layout.addWidget(combo) layout.addWidget(combo)
widget.show() widget.show()
app.exec_() app.exec_()

View File

@ -1,3 +1,4 @@
from bec_lib.callback_handler import EventType
from bec_lib.device import ReadoutPriority from bec_lib.device import ReadoutPriority
from bec_lib.logger import bec_logger from bec_lib.logger import bec_logger
from qtpy.QtCore import QSize, Signal, Slot from qtpy.QtCore import QSize, Signal, Slot
@ -29,6 +30,7 @@ class DeviceLineEdit(DeviceInputBase, QLineEdit):
""" """
device_selected = Signal(str) device_selected = Signal(str)
device_config_update = Signal()
ICON_NAME = "edit_note" ICON_NAME = "edit_note"
@ -46,6 +48,7 @@ class DeviceLineEdit(DeviceInputBase, QLineEdit):
default: str | None = None, default: str | None = None,
arg_name: str | None = None, arg_name: str | None = None,
): ):
self._callback_id = None
self._is_valid_input = False self._is_valid_input = False
self._accent_colors = get_accent_colors() self._accent_colors = get_accent_colors()
super().__init__(client=client, config=config, gui_id=gui_id) super().__init__(client=client, config=config, gui_id=gui_id)
@ -84,7 +87,28 @@ class DeviceLineEdit(DeviceInputBase, QLineEdit):
# Set default device if passed # Set default device if passed
if default is not None: if default is not None:
self.set_device(default) self.set_device(default)
self._callback_id = self.bec_dispatcher.client.callbacks.register(
EventType.DEVICE_UPDATE, self.on_device_update
)
self.device_config_update.connect(self.update_devices_from_filters)
self.textChanged.connect(self.check_validity) self.textChanged.connect(self.check_validity)
self.check_validity(self.text())
def on_device_update(self, action: str, content: dict) -> None:
"""
Callback for device update events. Triggers the device_update signal.
Args:
action (str): The action that triggered the event.
content (dict): The content of the config update.
"""
if action in ["add", "remove", "reload"]:
self.device_config_update.emit()
def cleanup(self):
"""Cleanup the widget."""
if self._callback_id is not None:
self.bec_dispatcher.client.callbacks.remove(self._callback_id)
def get_current_device(self) -> object: def get_current_device(self) -> object:
""" """

View File

@ -1,3 +1,4 @@
from bec_lib.device import Positioner
from ophyd import Kind from ophyd import Kind
from qtpy.QtCore import QSize, Signal, Slot from qtpy.QtCore import QSize, Signal, Slot
from qtpy.QtGui import QPainter, QPaintEvent, QPen from qtpy.QtGui import QPainter, QPaintEvent, QPen
@ -61,7 +62,8 @@ class SignalLineEdit(DeviceSignalInputBase, QLineEdit):
self.set_device(device) self.set_device(device)
if default is not None: if default is not None:
self.set_signal(default) self.set_signal(default)
self.textChanged.connect(self.check_validity) self.textChanged.connect(self.validate_device)
self.validate_device(self.text())
def get_current_device(self) -> object: def get_current_device(self) -> object:
""" """
@ -96,12 +98,30 @@ class SignalLineEdit(DeviceSignalInputBase, QLineEdit):
""" """
if self.validate_signal(input_text) is True: if self.validate_signal(input_text) is True:
self._is_valid_input = True self._is_valid_input = True
if self.validate_device(self.device) is True: self.on_text_changed(input_text)
self.device_signal_changed.emit(input_text)
else: else:
self._is_valid_input = False self._is_valid_input = False
self.update() self.update()
@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.
"""
print("test")
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 if __name__ == "__main__": # pragma: no cover
# pylint: disable=import-outside-toplevel # pylint: disable=import-outside-toplevel

View File

@ -5,7 +5,7 @@ import fakeredis
import pytest import pytest
from bec_lib.redis_connector import RedisConnector from bec_lib.redis_connector import RedisConnector
from bec_widgets.test_utils.client_mocks import DEVICES, DMMock, FakePositioner, Positioner from bec_widgets.tests.utils import DEVICES, DMMock, FakePositioner, Positioner
def fake_redis_server(host, port): def fake_redis_server(host, port):

View File

@ -4,7 +4,7 @@ import pytest
from bec_widgets.cli.client import BECFigure from bec_widgets.cli.client import BECFigure
from bec_widgets.cli.client_utils import BECGuiClientMixin, _start_plot_process from bec_widgets.cli.client_utils import BECGuiClientMixin, _start_plot_process
from bec_widgets.test_utils.client_mocks import FakeDevice from bec_widgets.tests.utils import FakeDevice
@pytest.fixture @pytest.fixture

View File

@ -3,9 +3,8 @@ from unittest import mock
import pytest import pytest
from bec_lib.device import ReadoutPriority from bec_lib.device import ReadoutPriority
from qtpy.QtWidgets import QWidget from qtpy.QtWidgets import QWidget
from typeguard import TypeCheckError
from bec_widgets.test_utils.client_mocks import FakePositioner from bec_widgets.tests.utils import FakePositioner
from bec_widgets.widgets.base_classes.device_input_base import BECDeviceFilter, DeviceInputBase from bec_widgets.widgets.base_classes.device_input_base import BECDeviceFilter, DeviceInputBase
from .client_mocks import mocked_client from .client_mocks import mocked_client
@ -26,8 +25,9 @@ def device_input_base(qtbot, mocked_client):
"""Fixture with mocked FilterIO and WidgetIO""" """Fixture with mocked FilterIO and WidgetIO"""
with mock.patch("bec_widgets.utils.filter_io.FilterIO.set_selection"): with mock.patch("bec_widgets.utils.filter_io.FilterIO.set_selection"):
with mock.patch("bec_widgets.utils.widget_io.WidgetIO.set_value"): with mock.patch("bec_widgets.utils.widget_io.WidgetIO.set_value"):
widget = create_widget(qtbot=qtbot, widget=DeviceInputWidget, client=mocked_client) with mock.patch("bec_widgets.utils.widget_io.WidgetIO.get_value"):
yield widget widget = create_widget(qtbot=qtbot, widget=DeviceInputWidget, client=mocked_client)
yield widget
def test_device_input_base_init(device_input_base): def test_device_input_base_init(device_input_base):

View File

@ -35,7 +35,6 @@ def test_device_input_combobox_init(device_input_combobox):
assert device_input_combobox.client is not None assert device_input_combobox.client is not None
assert isinstance(device_input_combobox, DeviceComboBox) assert isinstance(device_input_combobox, DeviceComboBox)
assert device_input_combobox.config.widget_class == "DeviceComboBox" assert device_input_combobox.config.widget_class == "DeviceComboBox"
assert device_input_combobox.config.default is None
assert device_input_combobox.devices == [ assert device_input_combobox.devices == [
"samx", "samx",
"samy", "samy",

View File

@ -90,23 +90,32 @@ def test_device_signal_set_device(device_signal_base):
assert device_signal_base.signals == ["readback", "setpoint", "velocity"] assert device_signal_base.signals == ["readback", "setpoint", "velocity"]
def test_signal_combobox(device_signal_combobox): def test_signal_combobox(qtbot, device_signal_combobox):
"""Test the signal_combobox""" """Test the signal_combobox"""
device_signal_combobox._signals == [] container = []
def test_cb(input):
container.append(input)
device_signal_combobox.device_signal_changed.connect(test_cb)
assert device_signal_combobox._signals == []
device_signal_combobox.include_normal_signals = True device_signal_combobox.include_normal_signals = True
device_signal_combobox.include_hinted_signals = True device_signal_combobox.include_hinted_signals = True
device_signal_combobox.include_config_signals = True device_signal_combobox.include_config_signals = True
device_signal_combobox.signals == [] assert device_signal_combobox.signals == []
device_signal_combobox.set_device("samx") device_signal_combobox.set_device("samx")
device_signal_combobox.signals == ["readback", "setpoint", "velocity"] assert device_signal_combobox.signals == ["readback", "setpoint", "velocity"]
qtbot.wait(100)
assert container == ["samx"]
def test_signal_lineeidt(device_signal_line_edit): def test_signal_lineeidt(device_signal_line_edit):
"""Test the signal_combobox""" """Test the signal_combobox"""
device_signal_line_edit._signals == []
assert device_signal_line_edit._signals == []
device_signal_line_edit.include_normal_signals = True device_signal_line_edit.include_normal_signals = True
device_signal_line_edit.include_hinted_signals = True device_signal_line_edit.include_hinted_signals = True
device_signal_line_edit.include_config_signals = True device_signal_line_edit.include_config_signals = True
device_signal_line_edit.signals == [] assert device_signal_line_edit.signals == []
device_signal_line_edit.set_device("samx") device_signal_line_edit.set_device("samx")
device_signal_line_edit.signals == ["readback", "setpoint", "velocity"] assert device_signal_line_edit.signals == ["readback", "setpoint", "velocity"]