mirror of
https://github.com/bec-project/bec_widgets.git
synced 2025-07-13 11:11:49 +02:00
refactor: move device config form to module
This commit is contained in:
@ -8,11 +8,12 @@ from bec_lib.logger import bec_logger
|
|||||||
from bec_qthemes import material_icon
|
from bec_qthemes import material_icon
|
||||||
from pydantic import BaseModel, ValidationError
|
from pydantic import BaseModel, ValidationError
|
||||||
from qtpy.QtCore import Signal # type: ignore
|
from qtpy.QtCore import Signal # type: ignore
|
||||||
from qtpy.QtWidgets import QGridLayout, QLabel, QLayout, QSizePolicy, QVBoxLayout, QWidget
|
from qtpy.QtWidgets import QApplication, QGridLayout, QLabel, QVBoxLayout, QWidget
|
||||||
|
|
||||||
from bec_widgets.utils.bec_widget import BECWidget
|
from bec_widgets.utils.bec_widget import BECWidget
|
||||||
from bec_widgets.utils.compact_popup import CompactPopupWidget
|
from bec_widgets.utils.compact_popup import CompactPopupWidget
|
||||||
from bec_widgets.utils.error_popups import SafeProperty
|
from bec_widgets.utils.error_popups import SafeProperty
|
||||||
|
from bec_widgets.utils.forms_from_types import styles
|
||||||
from bec_widgets.utils.forms_from_types.items import (
|
from bec_widgets.utils.forms_from_types.items import (
|
||||||
DynamicFormItem,
|
DynamicFormItem,
|
||||||
DynamicFormItemType,
|
DynamicFormItemType,
|
||||||
@ -207,6 +208,18 @@ class PydanticModelForm(TypedForm):
|
|||||||
self._layout.addWidget(self._validity)
|
self._layout.addWidget(self._validity)
|
||||||
self.value_changed.connect(self.validate_form)
|
self.value_changed.connect(self.validate_form)
|
||||||
|
|
||||||
|
self._connect_to_theme_change()
|
||||||
|
|
||||||
|
def set_pretty_display_theme(self, theme: str = "dark"):
|
||||||
|
if self._pretty_display:
|
||||||
|
self.setStyleSheet(styles.pretty_display_theme(theme))
|
||||||
|
|
||||||
|
def _connect_to_theme_change(self):
|
||||||
|
"""Connect to the theme change signal."""
|
||||||
|
qapp = QApplication.instance()
|
||||||
|
if hasattr(qapp, "theme_signal"):
|
||||||
|
qapp.theme_signal.theme_updated.connect(self.set_pretty_display_theme) # type: ignore
|
||||||
|
|
||||||
def set_schema(self, schema: type[BaseModel]):
|
def set_schema(self, schema: type[BaseModel]):
|
||||||
self._md_schema = schema
|
self._md_schema = schema
|
||||||
self.populate()
|
self.populate()
|
||||||
|
@ -0,0 +1,35 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from bec_lib.atlas_models import Device as DeviceConfigModel
|
||||||
|
from qtpy.QtWidgets import QApplication
|
||||||
|
|
||||||
|
from bec_widgets.utils.colors import get_theme_name
|
||||||
|
from bec_widgets.utils.forms_from_types import styles
|
||||||
|
from bec_widgets.utils.forms_from_types.forms import PydanticModelForm
|
||||||
|
|
||||||
|
|
||||||
|
class DeviceConfigForm(PydanticModelForm):
|
||||||
|
RPC = False
|
||||||
|
PLUGIN = False
|
||||||
|
|
||||||
|
def __init__(self, parent=None, client=None, pretty_display=False, **kwargs):
|
||||||
|
super().__init__(
|
||||||
|
parent=parent,
|
||||||
|
data_model=DeviceConfigModel,
|
||||||
|
pretty_display=pretty_display,
|
||||||
|
client=client,
|
||||||
|
**kwargs,
|
||||||
|
)
|
||||||
|
self._validity.setVisible(False)
|
||||||
|
self._connect_to_theme_change()
|
||||||
|
|
||||||
|
def set_pretty_display_theme(self, theme: str | None = None):
|
||||||
|
if theme is None:
|
||||||
|
theme = get_theme_name()
|
||||||
|
self.setStyleSheet(styles.pretty_display_theme(theme))
|
||||||
|
|
||||||
|
def _connect_to_theme_change(self):
|
||||||
|
"""Connect to the theme change signal."""
|
||||||
|
qapp = QApplication.instance()
|
||||||
|
if hasattr(qapp, "theme_signal"):
|
||||||
|
qapp.theme_signal.theme_updated.connect(self.set_pretty_display_theme) # type: ignore
|
@ -8,11 +8,11 @@ from qtpy.QtCore import QMimeData, QSize, Qt, Signal
|
|||||||
from qtpy.QtGui import QDrag
|
from qtpy.QtGui import QDrag
|
||||||
from qtpy.QtWidgets import QApplication, QHBoxLayout, QWidget
|
from qtpy.QtWidgets import QApplication, QHBoxLayout, QWidget
|
||||||
|
|
||||||
from bec_widgets.utils.colors import get_theme_name
|
|
||||||
from bec_widgets.utils.error_popups import SafeSlot
|
from bec_widgets.utils.error_popups import SafeSlot
|
||||||
from bec_widgets.utils.expandable_frame import ExpandableGroupFrame
|
from bec_widgets.utils.expandable_frame import ExpandableGroupFrame
|
||||||
from bec_widgets.utils.forms_from_types import styles
|
from bec_widgets.widgets.services.device_browser.device_item.device_config_form import (
|
||||||
from bec_widgets.utils.forms_from_types.forms import PydanticModelForm
|
DeviceConfigForm,
|
||||||
|
)
|
||||||
from bec_widgets.widgets.utility.visual.dark_mode_button.dark_mode_button import DarkModeButton
|
from bec_widgets.widgets.utility.visual.dark_mode_button.dark_mode_button import DarkModeButton
|
||||||
|
|
||||||
if TYPE_CHECKING: # pragma: no cover
|
if TYPE_CHECKING: # pragma: no cover
|
||||||
@ -21,33 +21,6 @@ if TYPE_CHECKING: # pragma: no cover
|
|||||||
logger = bec_logger.logger
|
logger = bec_logger.logger
|
||||||
|
|
||||||
|
|
||||||
class DeviceItemForm(PydanticModelForm):
|
|
||||||
RPC = False
|
|
||||||
PLUGIN = False
|
|
||||||
|
|
||||||
def __init__(self, parent=None, client=None, pretty_display=False, **kwargs):
|
|
||||||
super().__init__(
|
|
||||||
parent=parent,
|
|
||||||
data_model=DeviceConfigModel,
|
|
||||||
pretty_display=pretty_display,
|
|
||||||
client=client,
|
|
||||||
**kwargs,
|
|
||||||
)
|
|
||||||
self._validity.setVisible(False)
|
|
||||||
self._connect_to_theme_change()
|
|
||||||
|
|
||||||
def set_pretty_display_theme(self, theme: str | None = None):
|
|
||||||
if theme is None:
|
|
||||||
theme = get_theme_name()
|
|
||||||
self.setStyleSheet(styles.pretty_display_theme(theme))
|
|
||||||
|
|
||||||
def _connect_to_theme_change(self):
|
|
||||||
"""Connect to the theme change signal."""
|
|
||||||
qapp = QApplication.instance()
|
|
||||||
if hasattr(qapp, "theme_signal"):
|
|
||||||
qapp.theme_signal.theme_updated.connect(self.set_pretty_display_theme) # type: ignore
|
|
||||||
|
|
||||||
|
|
||||||
class DeviceItem(ExpandableGroupFrame):
|
class DeviceItem(ExpandableGroupFrame):
|
||||||
broadcast_size_hint = Signal(QSize)
|
broadcast_size_hint = Signal(QSize)
|
||||||
|
|
||||||
@ -72,7 +45,7 @@ class DeviceItem(ExpandableGroupFrame):
|
|||||||
def switch_expanded_state(self):
|
def switch_expanded_state(self):
|
||||||
if not self.expanded and not self._expanded_first_time:
|
if not self.expanded and not self._expanded_first_time:
|
||||||
self._expanded_first_time = True
|
self._expanded_first_time = True
|
||||||
self.form = DeviceItemForm(parent=self, pretty_display=True)
|
self.form = DeviceConfigForm(parent=self, pretty_display=True)
|
||||||
self._contents.layout().addWidget(self.form)
|
self._contents.layout().addWidget(self.form)
|
||||||
if self._data:
|
if self._data:
|
||||||
self.form.set_data(self._data)
|
self.form.set_data(self._data)
|
||||||
@ -125,7 +98,7 @@ if __name__ == "__main__": # pragma: no cover
|
|||||||
widget = QWidget()
|
widget = QWidget()
|
||||||
layout = QHBoxLayout()
|
layout = QHBoxLayout()
|
||||||
widget.setLayout(layout)
|
widget.setLayout(layout)
|
||||||
item = DeviceItem("Device")
|
item = DeviceItem(widget, "Device")
|
||||||
layout.addWidget(DarkModeButton())
|
layout.addWidget(DarkModeButton())
|
||||||
layout.addWidget(item)
|
layout.addWidget(item)
|
||||||
item.set_display_config(
|
item.set_display_config(
|
||||||
|
@ -5,7 +5,9 @@ import pytest
|
|||||||
from qtpy.QtCore import QPoint, Qt
|
from qtpy.QtCore import QPoint, Qt
|
||||||
|
|
||||||
from bec_widgets.widgets.services.device_browser.device_browser import DeviceBrowser
|
from bec_widgets.widgets.services.device_browser.device_browser import DeviceBrowser
|
||||||
from bec_widgets.widgets.services.device_browser.device_item.device_item import DeviceItemForm
|
from bec_widgets.widgets.services.device_browser.device_item.device_config_form import (
|
||||||
|
DeviceConfigForm,
|
||||||
|
)
|
||||||
|
|
||||||
from .client_mocks import mocked_client
|
from .client_mocks import mocked_client
|
||||||
|
|
||||||
@ -84,7 +86,7 @@ def test_device_item_expansion(device_browser, qtbot):
|
|||||||
widget: DeviceItem = device_browser.ui.device_list.itemWidget(device_item)
|
widget: DeviceItem = device_browser.ui.device_list.itemWidget(device_item)
|
||||||
qtbot.mouseClick(widget._expansion_button, Qt.MouseButton.LeftButton)
|
qtbot.mouseClick(widget._expansion_button, Qt.MouseButton.LeftButton)
|
||||||
form = widget._contents.layout().itemAt(0).widget()
|
form = widget._contents.layout().itemAt(0).widget()
|
||||||
qtbot.waitUntil(lambda: isinstance(form, DeviceItemForm), timeout=500)
|
qtbot.waitUntil(lambda: isinstance(form, DeviceConfigForm), timeout=500)
|
||||||
assert widget.expanded
|
assert widget.expanded
|
||||||
assert (name_field := form.widget_dict.get("name")) is not None
|
assert (name_field := form.widget_dict.get("name")) is not None
|
||||||
assert name_field.getValue() == "samx"
|
assert name_field.getValue() == "samx"
|
||||||
|
Reference in New Issue
Block a user