From c3625cb93bbf62b20205f950db7fb3ee2b178eb5 Mon Sep 17 00:00:00 2001 From: wyzula-jan Date: Tue, 12 May 2026 14:57:38 +0200 Subject: [PATCH] fix(scan_control): restore scan parameters from history are fetched on demand with button --- .../control/scan_control/scan_control.py | 26 +++----------- tests/unit_tests/test_scan_control.py | 34 +++++++++++++++++-- 2 files changed, 37 insertions(+), 23 deletions(-) diff --git a/bec_widgets/widgets/control/scan_control/scan_control.py b/bec_widgets/widgets/control/scan_control/scan_control.py index b5cb4722..b475dcfc 100644 --- a/bec_widgets/widgets/control/scan_control/scan_control.py +++ b/bec_widgets/widgets/control/scan_control/scan_control.py @@ -26,7 +26,6 @@ from bec_widgets.utils.error_popups import SafeProperty, SafeSlot from bec_widgets.widgets.control.buttons.stop_button.stop_button import StopButton from bec_widgets.widgets.control.scan_control.scan_group_box import ScanGroupBox from bec_widgets.widgets.editors.scan_metadata.scan_metadata import ScanMetadata -from bec_widgets.widgets.utility.toggle.toggle import ToggleSwitch class ScanParameterConfig(BaseModel): @@ -84,7 +83,6 @@ class ScanControl(BECWidget, QWidget): self.kwarg_boxes = [] self.expert_mode = False # TODO implement in the future versions self.previous_scan = None - self.last_scan_found = None # Widget Default Parameters self.config.default_scan = default_scan @@ -123,17 +121,12 @@ class ScanControl(BECWidget, QWidget): scan_selection_layout.addWidget(self.comboBox_scan_selection, 1) self.scan_selection_group.layout().addLayout(scan_selection_layout) - # Label to reload the last scan parameters within scan selection group box - self.toggle_layout = QHBoxLayout() - self.toggle_layout.addSpacerItem( - QSpacerItem(0, 0, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Fixed) + # Button to reload the last scan parameters on demand. + self.last_scan_button = QPushButton( + "Restore last scan parameters", self.scan_selection_group ) - self.last_scan_label = QLabel("Restore last scan parameters", self.scan_selection_group) - self.toggle = ToggleSwitch(parent=self.scan_selection_group, checked=False) - self.toggle.enabled.connect(self.request_last_executed_scan_parameters) - self.toggle_layout.addWidget(self.last_scan_label) - self.toggle_layout.addWidget(self.toggle) - self.scan_selection_group.layout().addLayout(self.toggle_layout) + self.last_scan_button.clicked.connect(self.request_last_executed_scan_parameters) + self.scan_selection_group.layout().addWidget(self.last_scan_button) self.scan_selection_group.setSizePolicy( QSizePolicy.Policy.Preferred, QSizePolicy.Policy.Fixed ) @@ -206,7 +199,6 @@ class ScanControl(BECWidget, QWidget): """Callback for scan selection combo box""" selected_scan_name = self.comboBox_scan_selection.currentText() self.scan_selected.emit(selected_scan_name) - self.request_last_executed_scan_parameters() self.restore_scan_parameters(selected_scan_name) @SafeSlot() @@ -215,10 +207,6 @@ class ScanControl(BECWidget, QWidget): """ Requests the last executed scan parameters from BEC and restores them to the scan control widget. """ - self.last_scan_found = False - if not self.toggle.checked: - return - current_scan = self.comboBox_scan_selection.currentText() history = ( self.client.connector.xread( @@ -246,8 +234,6 @@ class ScanControl(BECWidget, QWidget): if merged and self.kwarg_boxes: for box in self.kwarg_boxes: box.set_parameters(merged) - - self.last_scan_found = True break @SafeProperty(str) @@ -496,8 +482,6 @@ class ScanControl(BECWidget, QWidget): Args: scan_name(str): Name of the scan to restore the parameters for. """ - if self.last_scan_found is True: - return scan_params = self.config.scans.get(scan_name, None) if scan_params is None and self.previous_scan is None: return diff --git a/tests/unit_tests/test_scan_control.py b/tests/unit_tests/test_scan_control.py index 622755e8..4986e403 100644 --- a/tests/unit_tests/test_scan_control.py +++ b/tests/unit_tests/test_scan_control.py @@ -503,12 +503,42 @@ def test_changing_scans_remember_parameters(scan_control, mocked_client): assert grid_kwargs["burst_at_each_point"] == kwargs["burst_at_each_point"] +def test_scan_selection_does_not_fetch_last_scan_parameters( + scan_control, mocked_client, monkeypatch +): + xread = MagicMock(wraps=mocked_client.connector.xread) + monkeypatch.setattr(mocked_client.connector, "xread", xread) + + scan_control.comboBox_scan_selection.setCurrentText("grid_scan") + + xread.assert_not_called() + + +def test_restore_last_scan_parameters_button_fetches_on_demand( + scan_control, mocked_client, qtbot, monkeypatch +): + scan_control.comboBox_scan_selection.setCurrentText("line_scan") + xread = MagicMock(wraps=mocked_client.connector.xread) + monkeypatch.setattr(mocked_client.connector, "xread", xread) + + qtbot.mouseClick(scan_control.last_scan_button, Qt.LeftButton) + + xread.assert_called_once_with( + MessageEndpoints.scan_history(), from_start=True, user_id=scan_control.object_name + ) + args, kwargs = scan_control.get_scan_parameters(bec_object=False) + assert args == ["samx", 0.0, 2.0] + assert kwargs["steps"] == 10 + assert kwargs["relative"] is False + assert kwargs["exp_time"] == 2 + + @pytest.mark.skip(reason="Unreliable - GH issue #1134") def test_get_scan_parameters_from_redis(scan_control, mocked_client): scan_name = "line_scan" scan_control.comboBox_scan_selection.setCurrentText(scan_name) - scan_control.toggle.checked = True + scan_control.last_scan_button.click() args, kwargs = scan_control.get_scan_parameters(bec_object=False) @@ -605,7 +635,7 @@ def test_restore_parameters_with_fewer_arg_bundles(scan_control, qtbot): assert scan_control.arg_box.count_arg_rows() == 3 # Trigger restore of parameters from history - scan_control.toggle.checked = True + scan_control.last_scan_button.click() qtbot.wait(200) # After restore, arg_box should have only one bundle (the history size)