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

fix: grid formatting in TypedForm

This commit is contained in:
2025-06-02 15:18:07 +02:00
parent d9e5231d54
commit 797f72b28a
6 changed files with 27 additions and 14 deletions

View File

@ -8,7 +8,7 @@ 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, QVBoxLayout, QWidget from qtpy.QtWidgets import QGridLayout, QLabel, QLayout, QSizePolicy, 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
@ -59,10 +59,14 @@ class TypedForm(BECWidget, QWidget):
enabled (bool, optional): whether fields are enabled for editing. enabled (bool, optional): whether fields are enabled for editing.
pretty_display (bool, optional): Whether to use a pretty display for the widget. Defaults to False. If True, disables the widget, doesn't add a clear button, and adapts the stylesheet for non-editable display. pretty_display (bool, optional): Whether to use a pretty display for the widget. Defaults to False. If True, disables the widget, doesn't add a clear button, and adapts the stylesheet for non-editable display.
""" """
if (items is not None and form_item_specs is not None) or ( if items is not None and form_item_specs is not None:
items is None and form_item_specs is None logger.error(
): "Must specify one and only one of items and form_item_specs! Ignoring `items`."
raise ValueError("Must specify one and only one of items and form_item_specs") )
items = None
if items is None and form_item_specs is None:
logger.error("Must specify one and only one of items and form_item_specs!")
items = []
super().__init__(parent=parent, client=client, **kwargs) super().__init__(parent=parent, client=client, **kwargs)
self._items = ( self._items = (
form_item_specs form_item_specs
@ -72,6 +76,7 @@ class TypedForm(BECWidget, QWidget):
for name, item_type in items # type: ignore for name, item_type in items # type: ignore
] ]
) )
self.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.MinimumExpanding)
self._layout = QVBoxLayout() self._layout = QVBoxLayout()
self._layout.setContentsMargins(0, 0, 0, 0) self._layout.setContentsMargins(0, 0, 0, 0)
self.setLayout(self._layout) self.setLayout(self._layout)
@ -79,7 +84,11 @@ class TypedForm(BECWidget, QWidget):
self._enabled: bool = enabled self._enabled: bool = enabled
self._form_grid_container = QWidget(parent=self) self._form_grid_container = QWidget(parent=self)
self._form_grid_container.setSizePolicy(
QSizePolicy.MinimumExpanding, QSizePolicy.MinimumExpanding
)
self._form_grid = QWidget(parent=self._form_grid_container) self._form_grid = QWidget(parent=self._form_grid_container)
self._form_grid.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.MinimumExpanding)
self._layout.addWidget(self._form_grid_container) self._layout.addWidget(self._form_grid_container)
self._form_grid_container.setLayout(QVBoxLayout()) self._form_grid_container.setLayout(QVBoxLayout())
self._form_grid.setLayout(self._new_grid_layout()) self._form_grid.setLayout(self._new_grid_layout())
@ -100,6 +109,7 @@ class TypedForm(BECWidget, QWidget):
grid.addWidget(label, row, 0) grid.addWidget(label, row, 0)
widget = widget_from_type(item.item_type)(parent=self, spec=item) widget = widget_from_type(item.item_type)(parent=self, spec=item)
widget.valueChanged.connect(self.value_changed) widget.valueChanged.connect(self.value_changed)
widget.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.MinimumExpanding)
grid.addWidget(widget, row, 1) grid.addWidget(widget, row, 1)
def enumerate_form_widgets(self): def enumerate_form_widgets(self):
@ -125,7 +135,7 @@ class TypedForm(BECWidget, QWidget):
old_layout.deleteLater() old_layout.deleteLater()
self._form_grid.deleteLater() self._form_grid.deleteLater()
self._form_grid = QWidget() self._form_grid = QWidget()
self._form_grid.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.MinimumExpanding)
self._form_grid.setLayout(self._new_grid_layout()) self._form_grid.setLayout(self._new_grid_layout())
self._form_grid_container.layout().addWidget(self._form_grid) self._form_grid_container.layout().addWidget(self._form_grid)
@ -139,7 +149,6 @@ class TypedForm(BECWidget, QWidget):
def _new_grid_layout(self): def _new_grid_layout(self):
new_grid = QGridLayout() new_grid = QGridLayout()
new_grid.setContentsMargins(0, 0, 0, 0) new_grid.setContentsMargins(0, 0, 0, 0)
new_grid.setSizeConstraint(QLayout.SizeConstraint.SetFixedSize)
return new_grid return new_grid
@property @property

View File

@ -21,6 +21,7 @@ from qtpy.QtWidgets import (
QLayout, QLayout,
QLineEdit, QLineEdit,
QRadioButton, QRadioButton,
QSizePolicy,
QSpinBox, QSpinBox,
QToolButton, QToolButton,
QWidget, QWidget,
@ -145,6 +146,8 @@ class DynamicFormItem(QWidget):
self._desc = self._spec.info.description self._desc = self._spec.info.description
self.setLayout(self._layout) self.setLayout(self._layout)
self._add_main_widget() self._add_main_widget()
self._main_widget: QWidget
self._main_widget.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.MinimumExpanding)
if not spec.pretty_display: if not spec.pretty_display:
if clearable_required(spec.info): if clearable_required(spec.info):
self._add_clear_button() self._add_clear_button()

View File

@ -89,7 +89,7 @@ class ScanControl(BECWidget, QWidget):
self.config.allowed_scans = allowed_scans self.config.allowed_scans = allowed_scans
self._scan_metadata: dict | None = None self._scan_metadata: dict | None = None
self._metadata_form = ScanMetadata(parent=parent) self._metadata_form = ScanMetadata(parent=self)
# Create and set main layout # Create and set main layout
self._init_UI() self._init_UI()

View File

@ -2,6 +2,7 @@ from __future__ import annotations
from typing import Any from typing import Any
from qtpy import QtWidgets
from qtpy.QtCore import QAbstractTableModel, QModelIndex, Qt, Signal # type: ignore from qtpy.QtCore import QAbstractTableModel, QModelIndex, Qt, Signal # type: ignore
from qtpy.QtWidgets import ( from qtpy.QtWidgets import (
QApplication, QApplication,
@ -139,6 +140,8 @@ class DictBackedTable(QWidget):
QSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum) QSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum)
) )
self._table_view.setAlternatingRowColors(True) self._table_view.setAlternatingRowColors(True)
self._table_view.header().setSectionResizeMode(QtWidgets.QHeaderView.ResizeToContents)
self._table_view.header().setSectionResizeMode(5, QtWidgets.QHeaderView.Stretch)
self._layout.addWidget(self._table_view) self._layout.addWidget(self._table_view)
self._button_holder = QWidget() self._button_holder = QWidget()

View File

@ -50,12 +50,11 @@ def example_md():
@pytest.fixture @pytest.fixture
def model_widget(): def model_widget(qtbot):
widget = PydanticModelForm(data_model=ExampleSchema) widget = PydanticModelForm(data_model=ExampleSchema)
widget.populate() widget.populate()
qtbot.addWidget(widget)
yield widget yield widget
widget._clear_grid()
widget.deleteLater()
def test_widget_dict(model_widget: PydanticModelForm): def test_widget_dict(model_widget: PydanticModelForm):

View File

@ -62,12 +62,11 @@ def example_md():
@pytest.fixture @pytest.fixture
def empty_metadata_widget(): def empty_metadata_widget(qtbot):
widget = ScanMetadata() widget = ScanMetadata()
widget._additional_metadata._table_model._data = [["extra_field", "extra_data"]] widget._additional_metadata._table_model._data = [["extra_field", "extra_data"]]
qtbot.addWidget(widget)
yield widget yield widget
widget._clear_grid()
widget.deleteLater()
@pytest.fixture @pytest.fixture