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

refactor: BECWidget is a mixin based on BECConnector, for each QWidget in BEC

Handles closeEvent() and RPC registering/unregistering
This commit is contained in:
2024-07-16 16:36:46 +02:00
parent d64758f268
commit c7feb6952d
22 changed files with 62 additions and 103 deletions

View File

@ -1,6 +1,7 @@
from __future__ import annotations from __future__ import annotations
from bec_widgets.utils import BECConnector, ConnectionConfig from bec_widgets.utils import ConnectionConfig
from bec_widgets.utils.bec_widget import BECWidget
class DeviceInputConfig(ConnectionConfig): class DeviceInputConfig(ConnectionConfig):
@ -9,7 +10,7 @@ class DeviceInputConfig(ConnectionConfig):
arg_name: str | None = None arg_name: str | None = None
class DeviceInputBase(BECConnector): class DeviceInputBase(BECWidget):
""" """
Mixin class for device input widgets. This class provides methods to get the device list and device object based 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. on the current text of the widget.
@ -120,6 +121,3 @@ class DeviceInputBase(BECConnector):
""" """
if device not in self.get_device_list(self.config.device_filter): if device not in self.get_device_list(self.config.device_filter):
raise ValueError(f"Device {device} is not valid.") raise ValueError(f"Device {device} is not valid.")
def cleanup(self):
super().cleanup()

View File

@ -2,10 +2,11 @@ from bec_lib.endpoints import MessageEndpoints
from qtpy.QtCore import Qt, Slot from qtpy.QtCore import Qt, Slot
from qtpy.QtWidgets import QHeaderView, QTableWidget, QTableWidgetItem, QWidget from qtpy.QtWidgets import QHeaderView, QTableWidget, QTableWidgetItem, QWidget
from bec_widgets.utils.bec_connector import BECConnector, ConnectionConfig from bec_widgets.utils.bec_connector import ConnectionConfig
from bec_widgets.utils.bec_widget import BECWidget
class BECQueue(BECConnector, QTableWidget): class BECQueue(BECWidget, QTableWidget):
""" """
Widget to display the BEC queue. Widget to display the BEC queue.
""" """

View File

@ -13,7 +13,7 @@ from bec_lib.utils.import_utils import lazy_import_from
from qtpy.QtCore import QObject, QTimer, Signal, Slot from qtpy.QtCore import QObject, QTimer, Signal, Slot
from qtpy.QtWidgets import QHBoxLayout, QTreeWidget, QTreeWidgetItem, QWidget from qtpy.QtWidgets import QHBoxLayout, QTreeWidget, QTreeWidgetItem, QWidget
from bec_widgets.utils.bec_connector import BECConnector from bec_widgets.utils.bec_widget import BECWidget
from bec_widgets.utils.colors import apply_theme from bec_widgets.utils.colors import apply_theme
from bec_widgets.widgets.bec_status_box.status_item import StatusItem from bec_widgets.widgets.bec_status_box.status_item import StatusItem
@ -57,7 +57,7 @@ class BECServiceStatusMixin(QObject):
self.services_update.emit(self.client._services_info, self.client._services_metric) self.services_update.emit(self.client._services_info, self.client._services_metric)
class BECStatusBox(BECConnector, QWidget): class BECStatusBox(BECWidget, QWidget):
"""An autonomous widget to display the status of BEC services. """An autonomous widget to display the status of BEC services.
Args: Args:
@ -290,15 +290,6 @@ class BECStatusBox(BECConnector, QWidget):
if objects["item"] == item: if objects["item"] == item:
objects["widget"].show_popup() objects["widget"].show_popup()
def closeEvent(self, event):
"""Upon closing the widget, clean up the BECStatusBox and the QWidget.
Args:
event: The close event.
"""
super().cleanup()
super().closeEvent(event)
def main(): def main():
"""Main method to run the BECStatusBox widget.""" """Main method to run the BECStatusBox widget."""

View File

@ -8,11 +8,11 @@ from qtpy.QtGui import QDoubleValidator
from qtpy.QtWidgets import QDoubleSpinBox, QVBoxLayout, QWidget from qtpy.QtWidgets import QDoubleSpinBox, QVBoxLayout, QWidget
from bec_widgets.utils import UILoader from bec_widgets.utils import UILoader
from bec_widgets.utils.bec_connector import BECConnector from bec_widgets.utils.bec_widget import BECWidget
from bec_widgets.utils.colors import apply_theme from bec_widgets.utils.colors import apply_theme
class DeviceBox(BECConnector, QWidget): class DeviceBox(BECWidget, QWidget):
device_changed = Signal(str, str) device_changed = Signal(str, str)
def __init__(self, parent=None, device=None, *args, **kwargs): def __init__(self, parent=None, device=None, *args, **kwargs):

View File

@ -2,6 +2,7 @@ from typing import TYPE_CHECKING
from qtpy.QtWidgets import QComboBox from qtpy.QtWidgets import QComboBox
from bec_widgets.utils.bec_widget import BECWidget
from bec_widgets.widgets.base_classes.device_input_base import DeviceInputBase, DeviceInputConfig from bec_widgets.widgets.base_classes.device_input_base import DeviceInputBase, DeviceInputConfig
if TYPE_CHECKING: if TYPE_CHECKING:
@ -82,11 +83,3 @@ class DeviceComboBox(DeviceInputBase, QComboBox):
if device_obj is None: if device_obj is None:
raise ValueError(f"Device {device_name} is not found.") raise ValueError(f"Device {device_name} is not found.")
return device_obj return device_obj
def cleanup(self):
"""Cleanup the widget."""
super().cleanup()
def closeEvent(self, event):
super().cleanup()
return QComboBox.closeEvent(self, event)

View File

@ -3,6 +3,7 @@ from typing import TYPE_CHECKING
from qtpy.QtCore import QSize from qtpy.QtCore import QSize
from qtpy.QtWidgets import QCompleter, QLineEdit, QSizePolicy from qtpy.QtWidgets import QCompleter, QLineEdit, QSizePolicy
from bec_widgets.utils.bec_widget import BECWidget
from bec_widgets.widgets.base_classes.device_input_base import DeviceInputBase, DeviceInputConfig from bec_widgets.widgets.base_classes.device_input_base import DeviceInputBase, DeviceInputConfig
if TYPE_CHECKING: if TYPE_CHECKING:
@ -33,8 +34,8 @@ class DeviceLineEdit(DeviceInputBase, QLineEdit):
default: str | None = None, default: str | None = None,
arg_name: str | None = None, arg_name: str | None = None,
): ):
super().__init__(client=client, config=config, gui_id=gui_id)
QLineEdit.__init__(self, parent=parent) QLineEdit.__init__(self, parent=parent)
DeviceInputBase.__init__(self, client=client, config=config, gui_id=gui_id)
self.completer = QCompleter(self) self.completer = QCompleter(self)
self.setCompleter(self.completer) self.setCompleter(self.completer)
@ -94,11 +95,3 @@ class DeviceLineEdit(DeviceInputBase, QLineEdit):
if device_obj is None: if device_obj is None:
raise ValueError(f"Device {device_name} is not found.") raise ValueError(f"Device {device_name} is not found.")
return device_obj return device_obj
def cleanup(self):
"""Cleanup the widget."""
super().cleanup()
def closeEvent(self, event):
super().cleanup()
return QLineEdit.closeEvent(self, event)

View File

@ -6,7 +6,8 @@ from pydantic import Field
from pyqtgraph.dockarea import Dock from pyqtgraph.dockarea import Dock
from bec_widgets.cli.rpc_wigdet_handler import widget_handler from bec_widgets.cli.rpc_wigdet_handler import widget_handler
from bec_widgets.utils import BECConnector, ConnectionConfig, GridLayoutManager from bec_widgets.utils import ConnectionConfig, GridLayoutManager
from bec_widgets.utils.bec_widget import BECWidget
if TYPE_CHECKING: if TYPE_CHECKING:
from qtpy.QtWidgets import QWidget from qtpy.QtWidgets import QWidget
@ -24,7 +25,7 @@ class DockConfig(ConnectionConfig):
) )
class BECDock(BECConnector, Dock): class BECDock(BECWidget, Dock):
USER_ACCESS = [ USER_ACCESS = [
"_config_dict", "_config_dict",
"_rpc_id", "_rpc_id",
@ -91,7 +92,7 @@ class BECDock(BECConnector, Dock):
super().float() super().float()
@property @property
def widget_list(self) -> list[BECConnector]: def widget_list(self) -> list[BECWidget]:
""" """
Get the widgets in the dock. Get the widgets in the dock.
@ -101,7 +102,7 @@ class BECDock(BECConnector, Dock):
return self.widgets return self.widgets
@widget_list.setter @widget_list.setter
def widget_list(self, value: list[BECConnector]): def widget_list(self, value: list[BECWidget]):
self.widgets = value self.widgets = value
def hide_title_bar(self): def hide_title_bar(self):
@ -153,13 +154,13 @@ class BECDock(BECConnector, Dock):
def add_widget( def add_widget(
self, self,
widget: BECConnector | str, widget: BECWidget | str,
row=None, row=None,
col=0, col=0,
rowspan=1, rowspan=1,
colspan=1, colspan=1,
shift: Literal["down", "up", "left", "right"] = "down", shift: Literal["down", "up", "left", "right"] = "down",
) -> BECConnector: ) -> BECWidget:
""" """
Add a widget to the dock. Add a widget to the dock.
@ -236,8 +237,8 @@ class BECDock(BECConnector, Dock):
Clean up the dock, including all its widgets. Clean up the dock, including all its widgets.
""" """
for widget in self.widgets: for widget in self.widgets:
if hasattr(widget, "cleanup"): widget.cleanup()
widget.cleanup() self.widgets.clear()
super().cleanup() super().cleanup()
def close(self): def close(self):

View File

@ -9,7 +9,8 @@ from qtpy.QtCore import Qt
from qtpy.QtGui import QPainter, QPaintEvent from qtpy.QtGui import QPainter, QPaintEvent
from qtpy.QtWidgets import QWidget from qtpy.QtWidgets import QWidget
from bec_widgets.utils import BECConnector, ConnectionConfig, WidgetContainerUtils from bec_widgets.utils import ConnectionConfig, WidgetContainerUtils
from bec_widgets.utils.bec_widget import BECWidget
from .dock import BECDock, DockConfig from .dock import BECDock, DockConfig
@ -21,7 +22,7 @@ class DockAreaConfig(ConnectionConfig):
) )
class BECDockArea(BECConnector, DockArea): class BECDockArea(BECWidget, DockArea):
USER_ACCESS = [ USER_ACCESS = [
"_config_dict", "_config_dict",
"panels", "panels",
@ -227,6 +228,7 @@ class BECDockArea(BECConnector, DockArea):
self.attach_all() self.attach_all()
for dock in dict(self.docks).values(): for dock in dict(self.docks).values():
dock.remove() dock.remove()
self.docks.clear()
def cleanup(self): def cleanup(self):
""" """

View File

@ -12,7 +12,8 @@ from qtpy.QtCore import Signal as pyqtSignal
from qtpy.QtWidgets import QWidget from qtpy.QtWidgets import QWidget
from typeguard import typechecked from typeguard import typechecked
from bec_widgets.utils import BECConnector, ConnectionConfig, WidgetContainerUtils from bec_widgets.utils import ConnectionConfig, WidgetContainerUtils
from bec_widgets.utils.bec_widget import BECWidget
from bec_widgets.utils.colors import apply_theme from bec_widgets.utils.colors import apply_theme
from bec_widgets.widgets.figure.plots.image.image import BECImageShow, ImageConfig from bec_widgets.widgets.figure.plots.image.image import BECImageShow, ImageConfig
from bec_widgets.widgets.figure.plots.motor_map.motor_map import BECMotorMap, MotorMapConfig from bec_widgets.widgets.figure.plots.motor_map.motor_map import BECMotorMap, MotorMapConfig
@ -108,7 +109,7 @@ class WidgetHandler:
return widget return widget
class BECFigure(BECConnector, pg.GraphicsLayoutWidget): class BECFigure(BECWidget, pg.GraphicsLayoutWidget):
USER_ACCESS = [ USER_ACCESS = [
"_rpc_id", "_rpc_id",
"_config_dict", "_config_dict",
@ -728,14 +729,9 @@ class BECFigure(BECConnector, pg.GraphicsLayoutWidget):
"""Clear all widgets from the figure and reset to default state""" """Clear all widgets from the figure and reset to default state"""
for widget in list(self._widgets.values()): for widget in list(self._widgets.values()):
widget.remove() widget.remove()
# self.clear() self._widgets.clear()
self._widgets = defaultdict(dict)
self.grid = [] self.grid = []
theme = self.config.theme theme = self.config.theme
self.config = FigureConfig( self.config = FigureConfig(
widget_class=self.__class__.__name__, gui_id=self.gui_id, theme=theme widget_class=self.__class__.__name__, gui_id=self.gui_id, theme=theme
) )
# def cleanup(self):
# self.clear_all()
# super().cleanup()

View File

@ -596,7 +596,4 @@ class BECImageShow(BECPlotBase):
self.bec_dispatcher.disconnect_slot( self.bec_dispatcher.disconnect_slot(
self.on_image_update, MessageEndpoints.device_monitor(monitor) self.on_image_update, MessageEndpoints.device_monitor(monitor)
) )
for image in self.images: self.images.clear()
image.cleanup()
super().cleanup()

View File

@ -518,4 +518,3 @@ class BECMotorMap(BECPlotBase):
def cleanup(self): def cleanup(self):
"""Cleanup the widget.""" """Cleanup the widget."""
self._disconnect_current_motors() self._disconnect_current_motors()
super().cleanup()

View File

@ -296,9 +296,4 @@ class BECPlotBase(BECConnector, pg.GraphicsLayout):
def remove(self): def remove(self):
"""Remove the plot widget from the figure.""" """Remove the plot widget from the figure."""
if self.figure is not None: if self.figure is not None:
self.cleanup()
self.figure.remove(widget_id=self.gui_id) self.figure.remove(widget_id=self.gui_id)
def cleanup(self):
"""Cleanup the plot widget."""
super().cleanup()

View File

@ -1368,6 +1368,4 @@ class BECWaveform(BECPlotBase):
self.on_async_readback, self.on_async_readback,
MessageEndpoints.device_async_readback(self.scan_id, curve_id), MessageEndpoints.device_async_readback(self.scan_id, curve_id),
) )
for curve in self.curves: self.curves.clear()
curve.cleanup()
super().cleanup()

View File

@ -262,4 +262,4 @@ class BECCurve(BECConnector, pg.PlotDataItem):
"""Remove the curve from the plot.""" """Remove the curve from the plot."""
# self.parent_item.removeItem(self) # self.parent_item.removeItem(self)
self.parent_item.remove_curve(self.name()) self.parent_item.remove_curve(self.name())
self.cleanup() self.rpc_register.remove_rpc(self)

View File

@ -6,7 +6,7 @@ from qtpy.QtWidgets import QVBoxLayout, QWidget
from bec_widgets.qt_utils.settings_dialog import SettingsDialog from bec_widgets.qt_utils.settings_dialog import SettingsDialog
from bec_widgets.qt_utils.toolbar import ModularToolBar from bec_widgets.qt_utils.toolbar import ModularToolBar
from bec_widgets.utils import BECConnector from bec_widgets.utils.bec_widget import BECWidget
from bec_widgets.widgets.figure import BECFigure from bec_widgets.widgets.figure import BECFigure
from bec_widgets.widgets.figure.plots.motor_map.motor_map import MotorMapConfig from bec_widgets.widgets.figure.plots.motor_map.motor_map import MotorMapConfig
from bec_widgets.widgets.motor_map.motor_map_dialog.motor_map_settings import MotorMapSettings from bec_widgets.widgets.motor_map.motor_map_dialog.motor_map_settings import MotorMapSettings
@ -18,7 +18,7 @@ from bec_widgets.widgets.motor_map.motor_map_dialog.motor_map_toolbar import (
) )
class BECMotorMapWidget(BECConnector, QWidget): class BECMotorMapWidget(BECWidget, QWidget):
USER_ACCESS = [ USER_ACCESS = [
"change_motors", "change_motors",
"set_max_points", "set_max_points",
@ -208,10 +208,6 @@ class BECMotorMapWidget(BECConnector, QWidget):
self.toolbar.widgets["motor_y"].device_combobox.cleanup() self.toolbar.widgets["motor_y"].device_combobox.cleanup()
return super().cleanup() return super().cleanup()
def closeEvent(self, event):
self.cleanup()
QWidget().closeEvent(event)
def main(): # pragma: no cover def main(): # pragma: no cover
from qtpy.QtWidgets import QApplication from qtpy.QtWidgets import QApplication

View File

@ -288,7 +288,3 @@ class Ring(BECConnector):
value = msg.get("signals").get(device).get("value") value = msg.get("signals").get(device).get("value")
self.set_value(value) self.set_value(value)
self.parent_progress_widget.update() self.parent_progress_widget.update()
def cleanup(self):
self.reset_connection()
super().cleanup()

View File

@ -10,7 +10,8 @@ from qtpy import QtCore, QtGui
from qtpy.QtCore import QSize, Slot from qtpy.QtCore import QSize, Slot
from qtpy.QtWidgets import QSizePolicy, QWidget from qtpy.QtWidgets import QSizePolicy, QWidget
from bec_widgets.utils import BECConnector, Colors, ConnectionConfig, EntryValidator from bec_widgets.utils import Colors, ConnectionConfig, EntryValidator
from bec_widgets.utils.bec_widget import BECWidget
from bec_widgets.widgets.ring_progress_bar.ring import Ring, RingConfig from bec_widgets.widgets.ring_progress_bar.ring import Ring, RingConfig
@ -66,7 +67,7 @@ class RingProgressBarConfig(ConnectionConfig):
_validate_colormap = field_validator("color_map")(Colors.validate_color_map) _validate_colormap = field_validator("color_map")(Colors.validate_color_map)
class RingProgressBar(BECConnector, QWidget): class RingProgressBar(BECWidget, QWidget):
USER_ACCESS = [ USER_ACCESS = [
"_get_all_rpc", "_get_all_rpc",
"_rpc_id", "_rpc_id",
@ -208,7 +209,7 @@ class RingProgressBar(BECConnector, QWidget):
index(int): Index of the progress bar to remove. index(int): Index of the progress bar to remove.
""" """
ring = self._find_ring_by_index(index) ring = self._find_ring_by_index(index)
ring.cleanup() ring.reset_connection()
self._rings.remove(ring) self._rings.remove(ring)
self.config.rings.remove(ring.config) self.config.rings.remove(ring.config)
self.config.num_bars -= 1 self.config.num_bars -= 1
@ -622,9 +623,8 @@ class RingProgressBar(BECConnector, QWidget):
def clear_all(self): def clear_all(self):
for ring in self._rings: for ring in self._rings:
ring.cleanup() ring.reset_connection()
del ring self._rings.clear()
self._rings = []
self.update() self.update()
self.initialize_bars() self.initialize_bars()
@ -633,6 +633,6 @@ class RingProgressBar(BECConnector, QWidget):
self.on_scan_queue_status, MessageEndpoints.scan_queue_status() self.on_scan_queue_status, MessageEndpoints.scan_queue_status()
) )
for ring in self._rings: for ring in self._rings:
ring.cleanup() ring.reset_connection()
del ring self._rings.clear()
super().cleanup() super().cleanup()

View File

@ -10,13 +10,13 @@ from qtpy.QtWidgets import (
QWidget, QWidget,
) )
from bec_widgets.utils import BECConnector from bec_widgets.utils.bec_widget import BECWidget
from bec_widgets.utils.colors import apply_theme from bec_widgets.utils.colors import apply_theme
from bec_widgets.widgets.scan_control.scan_group_box import ScanGroupBox from bec_widgets.widgets.scan_control.scan_group_box import ScanGroupBox
from bec_widgets.widgets.stop_button.stop_button import StopButton from bec_widgets.widgets.stop_button.stop_button import StopButton
class ScanControl(BECConnector, QWidget): class ScanControl(BECWidget, QWidget):
def __init__( def __init__(
self, parent=None, client=None, gui_id: str | None = None, allowed_scans: list | None = None self, parent=None, client=None, gui_id: str | None = None, allowed_scans: list | None = None
@ -196,10 +196,6 @@ class ScanControl(BECConnector, QWidget):
widget.cleanup() widget.cleanup()
super().cleanup() super().cleanup()
def closeEvent(self, event):
self.cleanup()
return QWidget.closeEvent(self, event)
# Application example # Application example
if __name__ == "__main__": # pragma: no cover if __name__ == "__main__": # pragma: no cover

View File

@ -1,10 +1,10 @@
from qtpy.QtCore import Slot from qtpy.QtCore import Slot
from qtpy.QtWidgets import QPushButton from qtpy.QtWidgets import QPushButton
from bec_widgets.utils import BECConnector from bec_widgets.utils.bec_widget import BECWidget
class StopButton(BECConnector, QPushButton): class StopButton(BECWidget, QPushButton):
"""A button that stops the current scan.""" """A button that stops the current scan."""
def __init__(self, parent=None, client=None, config=None, gui_id=None): def __init__(self, parent=None, client=None, config=None, gui_id=None):

View File

@ -3,7 +3,8 @@ import re
from pydantic import Field, field_validator from pydantic import Field, field_validator
from qtpy.QtWidgets import QTextEdit from qtpy.QtWidgets import QTextEdit
from bec_widgets.utils.bec_connector import BECConnector, ConnectionConfig from bec_widgets.utils.bec_connector import ConnectionConfig
from bec_widgets.utils.bec_widget import BECWidget
from bec_widgets.utils.colors import Colors from bec_widgets.utils.colors import Colors
@ -27,7 +28,7 @@ class TextBoxConfig(ConnectionConfig):
_validate_background_color = field_validator("background_color")(Colors.validate_color) _validate_background_color = field_validator("background_color")(Colors.validate_color)
class TextBox(BECConnector, QTextEdit): class TextBox(BECWidget, QTextEdit):
USER_ACCESS = ["set_color", "set_text", "set_font_size"] USER_ACCESS = ["set_color", "set_text", "set_font_size"]

View File

@ -2,7 +2,7 @@ from qtpy.QtCore import QUrl, qInstallMessageHandler
from qtpy.QtWebEngineWidgets import QWebEngineView from qtpy.QtWebEngineWidgets import QWebEngineView
from qtpy.QtWidgets import QApplication from qtpy.QtWidgets import QApplication
from bec_widgets.utils import BECConnector from bec_widgets.utils.bec_widget import BECWidget
def suppress_qt_messages(type_, context, msg): def suppress_qt_messages(type_, context, msg):
@ -14,7 +14,7 @@ def suppress_qt_messages(type_, context, msg):
qInstallMessageHandler(suppress_qt_messages) qInstallMessageHandler(suppress_qt_messages)
class WebsiteWidget(BECConnector, QWebEngineView): class WebsiteWidget(BECWidget, QWebEngineView):
""" """
A simple widget to display a website A simple widget to display a website
""" """

View File

@ -1,13 +1,19 @@
import pytest import pytest
from qtpy.QtWidgets import QWidget
from bec_widgets.widgets.base_classes.device_input_base import DeviceInputBase from bec_widgets.widgets.base_classes.device_input_base import DeviceInputBase
from .client_mocks import mocked_client from .client_mocks import mocked_client
# DeviceInputBase is meant to be mixed in a QWidget
class DeviceInputWidget(DeviceInputBase, QWidget):
pass
@pytest.fixture @pytest.fixture
def device_input_base(mocked_client): def device_input_base(mocked_client):
widget = DeviceInputBase(client=mocked_client) widget = DeviceInputWidget(client=mocked_client)
yield widget yield widget
@ -15,7 +21,7 @@ def test_device_input_base_init(device_input_base):
assert device_input_base is not None assert device_input_base is not None
assert device_input_base.client is not None assert device_input_base.client is not None
assert isinstance(device_input_base, DeviceInputBase) assert isinstance(device_input_base, DeviceInputBase)
assert device_input_base.config.widget_class == "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 is None
assert device_input_base.config.default is None assert device_input_base.config.default is None
assert device_input_base.devices == [] assert device_input_base.devices == []
@ -23,12 +29,12 @@ def test_device_input_base_init(device_input_base):
def test_device_input_base_init_with_config(mocked_client): def test_device_input_base_init_with_config(mocked_client):
config = { config = {
"widget_class": "DeviceInputBase", "widget_class": "DeviceInputWidget",
"gui_id": "test_gui_id", "gui_id": "test_gui_id",
"device_filter": "FakePositioner", "device_filter": "FakePositioner",
"default": "samx", "default": "samx",
} }
widget = DeviceInputBase(client=mocked_client, config=config) widget = DeviceInputWidget(client=mocked_client, config=config)
assert widget.config.gui_id == "test_gui_id" assert widget.config.gui_id == "test_gui_id"
assert widget.config.device_filter == "FakePositioner" assert widget.config.device_filter == "FakePositioner"
assert widget.config.default == "samx" assert widget.config.default == "samx"