mirror of
https://github.com/bec-project/bec_widgets.git
synced 2026-01-01 19:41:18 +01:00
wip
This commit is contained in:
@@ -17,7 +17,6 @@ from bec_widgets.utils.forms_from_types.items import (
|
||||
DynamicFormItem,
|
||||
DynamicFormItemType,
|
||||
FormItemSpec,
|
||||
default_widget_types,
|
||||
widget_from_type,
|
||||
)
|
||||
|
||||
@@ -93,7 +92,6 @@ class TypedForm(BECWidget, QWidget):
|
||||
self._layout.addWidget(self._form_grid_container)
|
||||
self._form_grid_container.setLayout(QVBoxLayout())
|
||||
self._form_grid.setLayout(self._new_grid_layout())
|
||||
self._widget_types = default_widget_types
|
||||
self._widget_from_type = widget_from_type
|
||||
self._post_init()
|
||||
|
||||
@@ -112,7 +110,7 @@ class TypedForm(BECWidget, QWidget):
|
||||
label.setProperty("_model_field_name", item.name)
|
||||
label.setToolTip(item.info.description or item.name)
|
||||
grid.addWidget(label, row, 0)
|
||||
widget = self._widget_from_type(item.item_type, self._widget_types)(parent=self, spec=item)
|
||||
widget = self._widget_from_type(item.item_type)(parent=self, spec=item)
|
||||
widget.valueChanged.connect(self.value_changed)
|
||||
widget.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.MinimumExpanding)
|
||||
grid.addWidget(widget, row, 1)
|
||||
@@ -144,9 +142,9 @@ class TypedForm(BECWidget, QWidget):
|
||||
self._form_grid.setLayout(self._new_grid_layout())
|
||||
self._form_grid_container.layout().addWidget(self._form_grid)
|
||||
|
||||
self.resize()
|
||||
self.update_size()
|
||||
|
||||
def resize(self):
|
||||
def update_size(self):
|
||||
self._form_grid.adjustSize()
|
||||
self._form_grid_container.adjustSize()
|
||||
self.adjustSize()
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import typing
|
||||
from abc import abstractmethod
|
||||
from decimal import Decimal
|
||||
from types import GenericAlias, UnionType
|
||||
from typing import Callable, Literal, TypedDict
|
||||
from typing import Callable, Final, Literal
|
||||
|
||||
from bec_lib.logger import bec_logger
|
||||
from bec_qthemes import material_icon
|
||||
@@ -125,7 +126,7 @@ class ClearableBoolEntry(QWidget):
|
||||
self._false.setToolTip(tooltip)
|
||||
|
||||
|
||||
DynamicFormItemType = str | int | float | Decimal | bool | dict
|
||||
DynamicFormItemType = str | int | float | Decimal | bool | dict | list
|
||||
|
||||
|
||||
class DynamicFormItem(QWidget):
|
||||
@@ -335,11 +336,28 @@ class DictMetadataField(DynamicFormItem):
|
||||
self._main_widget.replace_data(value)
|
||||
|
||||
|
||||
class ListMetadataField(DynamicFormItem):
|
||||
def __init__(self, *, parent: QWidget | None = None, spec: FormItemSpec) -> None:
|
||||
super().__init__(parent=parent, spec=spec)
|
||||
if spec.info.annotation is list:
|
||||
self.item_type = str
|
||||
elif isinstance(spec.info.annotation, GenericAlias):
|
||||
args = set(typing.get_args(spec.info.annotation))
|
||||
if args == set((str,)):
|
||||
self.item_type = str
|
||||
if args == set((int,)):
|
||||
self.item_type = int
|
||||
if args == set((float,)) or args == set((int, float)):
|
||||
self.item_type = float
|
||||
else:
|
||||
self.item_type = str
|
||||
|
||||
|
||||
WidgetTypeRegistry = dict[
|
||||
str, tuple[Callable[[type | UnionType | None], bool], type[DynamicFormItem]]
|
||||
]
|
||||
|
||||
default_widget_types: WidgetTypeRegistry = {
|
||||
DEFAULT_WIDGET_TYPES: Final[WidgetTypeRegistry] = {
|
||||
"str": (lambda anno: anno in [str, str | None, None], StrMetadataField),
|
||||
"int": (lambda anno: anno in [int, int | None], IntMetadataField),
|
||||
"float_decimal": (
|
||||
@@ -355,14 +373,15 @@ default_widget_types: WidgetTypeRegistry = {
|
||||
"list": (
|
||||
lambda anno: anno in [list, list | None]
|
||||
or (isinstance(anno, GenericAlias) and anno.__origin__ is list),
|
||||
StrMetadataField,
|
||||
ListMetadataField,
|
||||
),
|
||||
}
|
||||
|
||||
|
||||
def widget_from_type(
|
||||
annotation: type | UnionType | None, widget_types: WidgetTypeRegistry
|
||||
annotation: type | UnionType | None, widget_types: WidgetTypeRegistry | None = None
|
||||
) -> type[DynamicFormItem]:
|
||||
widget_types = widget_types or DEFAULT_WIDGET_TYPES
|
||||
for predicate, widget_type in widget_types.values():
|
||||
if predicate(annotation):
|
||||
return widget_type
|
||||
@@ -378,6 +397,8 @@ if __name__ == "__main__": # pragma: no cover
|
||||
value3: bool = Field(True)
|
||||
value4: int = Field(123)
|
||||
value5: int | None = Field()
|
||||
value6: list[int] = Field()
|
||||
value7: list = Field()
|
||||
|
||||
app = QApplication([])
|
||||
w = QWidget()
|
||||
|
||||
@@ -8,9 +8,9 @@ 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
|
||||
from bec_widgets.utils.forms_from_types.items import (
|
||||
DEFAULT_WIDGET_TYPES,
|
||||
BoolMetadataField,
|
||||
BoolToggleMetadataField,
|
||||
default_widget_types,
|
||||
)
|
||||
|
||||
|
||||
@@ -26,9 +26,9 @@ class DeviceConfigForm(PydanticModelForm):
|
||||
client=client,
|
||||
**kwargs,
|
||||
)
|
||||
self._widget_types = default_widget_types.copy()
|
||||
self._widget_types["bool"] = (lambda anno: anno == bool, BoolToggleMetadataField)
|
||||
self._widget_types["optional_bool"] = (lambda anno: anno == bool | None, BoolMetadataField)
|
||||
self._widget_types = DEFAULT_WIDGET_TYPES.copy()
|
||||
self._widget_types["bool"] = (lambda anno: anno is bool, BoolToggleMetadataField)
|
||||
self._widget_types["optional_bool"] = (lambda anno: anno is bool | None, BoolMetadataField)
|
||||
self._validity.setVisible(False)
|
||||
self._connect_to_theme_change()
|
||||
self.populate()
|
||||
|
||||
Reference in New Issue
Block a user