From 0a80bd0a9279cef1136a04c252c97e624ef2e779 Mon Sep 17 00:00:00 2001 From: David Perl Date: Tue, 25 Nov 2025 15:52:31 +0100 Subject: [PATCH] fix: remove ghost widgets in scan metadata --- bec_widgets/utils/forms_from_types/forms.py | 29 +++++++++---------- bec_widgets/utils/forms_from_types/items.py | 6 ++++ .../editors/scan_metadata/scan_metadata.py | 1 - 3 files changed, 20 insertions(+), 16 deletions(-) diff --git a/bec_widgets/utils/forms_from_types/forms.py b/bec_widgets/utils/forms_from_types/forms.py index db5ad7de..eb5e31e6 100644 --- a/bec_widgets/utils/forms_from_types/forms.py +++ b/bec_widgets/utils/forms_from_types/forms.py @@ -81,10 +81,11 @@ class TypedForm(BECWidget, QWidget): self._form_grid_container = QWidget(parent=self) self._form_grid_container.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Minimum) + self._form_grid_container.setLayout(QVBoxLayout()) + self._layout.addWidget(self._form_grid_container) + self._form_grid = QWidget(parent=self._form_grid_container) self._form_grid.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Minimum) - self._layout.addWidget(self._form_grid_container) - self._form_grid_container.setLayout(QVBoxLayout()) self._form_grid.setLayout(self._new_grid_layout()) self._widget_types: dict | None = None @@ -105,11 +106,11 @@ class TypedForm(BECWidget, QWidget): def _add_griditem(self, item: FormItemSpec, row: int): grid = self._form_grid.layout() - label = QLabel(item.name) + label = QLabel(parent=self._form_grid, text=item.name) 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, self._widget_types)(parent=self, spec=item) + widget = self._widget_from_type(item, self._widget_types)(parent=self._form_grid, spec=item) widget.valueChanged.connect(self.value_changed) widget.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Minimum) grid.addWidget(widget, row, 1) @@ -128,19 +129,17 @@ class TypedForm(BECWidget, QWidget): } def _clear_grid(self): - if (old_layout := self._form_grid.layout()) is not None: - while old_layout.count(): - item = old_layout.takeAt(0) - widget = item.widget() - if widget is not None: - widget.deleteLater() - old_layout.deleteLater() - self._form_grid.deleteLater() + gl = self._form_grid.layout() + while w := gl.takeAt(0): + w = w.widget() + if hasattr(w, "teardown"): + w.teardown() + w.deleteLater() + self._form_grid_container.layout().removeWidget(self._form_grid) + self._form_grid.deleteLater() self._form_grid = QWidget() - self._form_grid.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Minimum) self._form_grid.setLayout(self._new_grid_layout()) self._form_grid_container.layout().addWidget(self._form_grid) - self.update_size() def update_size(self): @@ -149,7 +148,7 @@ class TypedForm(BECWidget, QWidget): self.adjustSize() def _new_grid_layout(self): - new_grid = QGridLayout() + new_grid = QGridLayout(self) new_grid.setContentsMargins(0, 0, 0, 0) return new_grid diff --git a/bec_widgets/utils/forms_from_types/items.py b/bec_widgets/utils/forms_from_types/items.py index e9d92db6..6b77bb53 100644 --- a/bec_widgets/utils/forms_from_types/items.py +++ b/bec_widgets/utils/forms_from_types/items.py @@ -209,6 +209,12 @@ class DynamicFormItem(QWidget): def _value_changed(self, *_, **__): self.valueChanged.emit() + def teardown(self): + self._layout.deleteLater() + self._layout.removeWidget(self._main_widget) + self._main_widget.deleteLater() + self._main_widget = None + class StrFormItem(DynamicFormItem): def __init__(self, parent: QWidget | None = None, *, spec: FormItemSpec) -> None: diff --git a/bec_widgets/widgets/editors/scan_metadata/scan_metadata.py b/bec_widgets/widgets/editors/scan_metadata/scan_metadata.py index 742936df..3cee7b06 100644 --- a/bec_widgets/widgets/editors/scan_metadata/scan_metadata.py +++ b/bec_widgets/widgets/editors/scan_metadata/scan_metadata.py @@ -85,7 +85,6 @@ class ScanMetadata(PydanticModelForm): def set_schema_from_scan(self, scan_name: str | None): self._scan_name = scan_name or "" self.set_schema(get_metadata_schema_for_scan(self._scan_name)) - self.populate() if __name__ == "__main__": # pragma: no cover