fix(scan_control): box cleanups

This commit is contained in:
2026-07-08 16:59:07 +02:00
committed by Jan Wyzula
parent 1c05a17d5f
commit cd2141b27c
3 changed files with 27 additions and 9 deletions
@@ -469,6 +469,7 @@ class ScanControl(BECWidget, QWidget):
"""Clears the scan control layout from GuiGroups and ArgGroups boxes."""
if self.arg_box is not None:
self.layout.removeWidget(self.arg_box)
self.arg_box.close()
self.arg_box.deleteLater()
self.arg_box = None
if self.kwarg_boxes != []:
@@ -477,6 +478,7 @@ class ScanControl(BECWidget, QWidget):
def remove_kwarg_boxes(self):
for box in self.kwarg_boxes:
self.layout.removeWidget(box)
box.close()
box.deleteLater()
self.kwarg_boxes = []
@@ -554,15 +556,6 @@ class ScanControl(BECWidget, QWidget):
def cleanup(self):
"""Cleanup the scan control widget."""
self.button_stop_scan.cleanup()
if self.arg_box:
for widget in self.arg_box.widgets:
if hasattr(widget, "cleanup"):
widget.cleanup()
for kwarg_box in self.kwarg_boxes:
for widget in kwarg_box.widgets:
if hasattr(widget, "cleanup"):
widget.cleanup()
super().cleanup()
@@ -1,5 +1,6 @@
from typing import Literal, Sequence
import shiboken6
from bec_lib.logger import bec_logger
from bec_qthemes import material_icon
from qtpy.QtCore import Property, Qt, Signal, Slot
@@ -239,6 +240,13 @@ class ScanGroupBox(QGroupBox):
# margins. Host layouts should top-align or stretch below the box; ScanControl uses
# layout.setAlignment(Qt.AlignTop).
def closeEvent(self, event):
for widget in self.widgets:
if shiboken6.isValid(widget):
widget.close()
widget.deleteLater()
super().closeEvent(event)
def init_box(self, config: dict):
box_name = config.get("name", "ScanGroupBox")
self.inputs = config.get("inputs", {})
+17
View File
@@ -648,6 +648,23 @@ def test_current_scan(scan_control, mocked_client):
assert scan_control.current_scan == new_scan
def test_scan_switch_runs_cleanup_on_previous_inputs(scan_control):
"""Switching scans tears down the old group boxes; the BECWidget inputs inside
(device comboboxes) must go through close() so their cleanup runs, instead of
being destroyed by deleteLater() without cleanup."""
scan_control.comboBox_scan_selection.setCurrentText("line_scan")
old_inputs = [w for w in scan_control.arg_box.widgets if hasattr(w, "_destroyed")]
assert old_inputs, "line_scan arg box should contain at least one BECWidget input"
assert all(not w._destroyed for w in old_inputs)
scan_control.comboBox_scan_selection.setCurrentText("grid_scan")
# closeEvent ran cleanup and flagged each old input as destroyed
assert all(w._destroyed for w in old_inputs)
register = scan_control.rpc_register
assert all(not register.object_is_registered(w) for w in old_inputs)
@pytest.mark.parametrize("scan_name", ["line_scan", "grid_scan"])
def test_on_scan_selected(scan_control, scan_name):
expected_scan_info = available_scans_message.resource[scan_name]