diff --git a/bec_widgets/utils/forms_from_types/forms.py b/bec_widgets/utils/forms_from_types/forms.py index c31344fa..1fda8f57 100644 --- a/bec_widgets/utils/forms_from_types/forms.py +++ b/bec_widgets/utils/forms_from_types/forms.py @@ -8,7 +8,7 @@ from bec_lib.logger import bec_logger from bec_qthemes import material_icon from pydantic import BaseModel, ValidationError 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.compact_popup import CompactPopupWidget @@ -59,10 +59,14 @@ class TypedForm(BECWidget, QWidget): 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. """ - if (items is not None and form_item_specs is not None) or ( - items is None and form_item_specs is None - ): - raise ValueError("Must specify one and only one of items and form_item_specs") + if items is not None and form_item_specs is not None: + logger.error( + "Must specify one and only one of items and form_item_specs! Ignoring `items`." + ) + 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) self._items = ( form_item_specs @@ -72,6 +76,7 @@ class TypedForm(BECWidget, QWidget): for name, item_type in items # type: ignore ] ) + self.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.MinimumExpanding) self._layout = QVBoxLayout() self._layout.setContentsMargins(0, 0, 0, 0) self.setLayout(self._layout) @@ -79,7 +84,11 @@ class TypedForm(BECWidget, QWidget): self._enabled: bool = enabled 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.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.MinimumExpanding) self._layout.addWidget(self._form_grid_container) self._form_grid_container.setLayout(QVBoxLayout()) self._form_grid.setLayout(self._new_grid_layout()) @@ -100,6 +109,7 @@ class TypedForm(BECWidget, QWidget): grid.addWidget(label, row, 0) widget = 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) def enumerate_form_widgets(self): @@ -125,7 +135,7 @@ class TypedForm(BECWidget, QWidget): old_layout.deleteLater() self._form_grid.deleteLater() self._form_grid = QWidget() - + self._form_grid.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.MinimumExpanding) self._form_grid.setLayout(self._new_grid_layout()) self._form_grid_container.layout().addWidget(self._form_grid) @@ -139,7 +149,6 @@ class TypedForm(BECWidget, QWidget): def _new_grid_layout(self): new_grid = QGridLayout() new_grid.setContentsMargins(0, 0, 0, 0) - new_grid.setSizeConstraint(QLayout.SizeConstraint.SetFixedSize) return new_grid @property diff --git a/bec_widgets/utils/forms_from_types/items.py b/bec_widgets/utils/forms_from_types/items.py index c5807700..17a34143 100644 --- a/bec_widgets/utils/forms_from_types/items.py +++ b/bec_widgets/utils/forms_from_types/items.py @@ -21,6 +21,7 @@ from qtpy.QtWidgets import ( QLayout, QLineEdit, QRadioButton, + QSizePolicy, QSpinBox, QToolButton, QWidget, @@ -145,6 +146,8 @@ class DynamicFormItem(QWidget): self._desc = self._spec.info.description self.setLayout(self._layout) self._add_main_widget() + self._main_widget: QWidget + self._main_widget.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.MinimumExpanding) if not spec.pretty_display: if clearable_required(spec.info): self._add_clear_button() diff --git a/bec_widgets/widgets/control/scan_control/scan_control.py b/bec_widgets/widgets/control/scan_control/scan_control.py index 23a4976e..54bd7120 100644 --- a/bec_widgets/widgets/control/scan_control/scan_control.py +++ b/bec_widgets/widgets/control/scan_control/scan_control.py @@ -89,7 +89,7 @@ class ScanControl(BECWidget, QWidget): self.config.allowed_scans = allowed_scans self._scan_metadata: dict | None = None - self._metadata_form = ScanMetadata(parent=parent) + self._metadata_form = ScanMetadata(parent=self) # Create and set main layout self._init_UI() diff --git a/bec_widgets/widgets/editors/dict_backed_table.py b/bec_widgets/widgets/editors/dict_backed_table.py index f4b1ea9c..a8878ebc 100644 --- a/bec_widgets/widgets/editors/dict_backed_table.py +++ b/bec_widgets/widgets/editors/dict_backed_table.py @@ -2,6 +2,7 @@ from __future__ import annotations from typing import Any +from qtpy import QtWidgets from qtpy.QtCore import QAbstractTableModel, QModelIndex, Qt, Signal # type: ignore from qtpy.QtWidgets import ( QApplication, @@ -139,6 +140,8 @@ class DictBackedTable(QWidget): QSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum) ) 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._button_holder = QWidget() diff --git a/tests/unit_tests/test_pydantic_model_form.py b/tests/unit_tests/test_pydantic_model_form.py index 0841b868..1ddcb4d0 100644 --- a/tests/unit_tests/test_pydantic_model_form.py +++ b/tests/unit_tests/test_pydantic_model_form.py @@ -50,12 +50,11 @@ def example_md(): @pytest.fixture -def model_widget(): +def model_widget(qtbot): widget = PydanticModelForm(data_model=ExampleSchema) widget.populate() + qtbot.addWidget(widget) yield widget - widget._clear_grid() - widget.deleteLater() def test_widget_dict(model_widget: PydanticModelForm): diff --git a/tests/unit_tests/test_scan_metadata.py b/tests/unit_tests/test_scan_metadata.py index c7e19646..f9ddcd3b 100644 --- a/tests/unit_tests/test_scan_metadata.py +++ b/tests/unit_tests/test_scan_metadata.py @@ -62,12 +62,11 @@ def example_md(): @pytest.fixture -def empty_metadata_widget(): +def empty_metadata_widget(qtbot): widget = ScanMetadata() widget._additional_metadata._table_model._data = [["extra_field", "extra_data"]] + qtbot.addWidget(widget) yield widget - widget._clear_grid() - widget.deleteLater() @pytest.fixture