some fixes again

This commit is contained in:
Ayzen
2026-06-05 17:50:59 +03:00
parent bbea744459
commit 3c30a12d4a
24 changed files with 209 additions and 157 deletions
@@ -453,6 +453,7 @@ class AppWindowConfigStateBuildersMixin:
config.gpr,
input_switch_positions=config.input_switch.positions,
output_switch_positions=config.output_switch.positions,
sweep=config.radar.sweep,
)
return config
@@ -72,17 +72,11 @@ class AppWindowControlButtonMixin:
Delivered as a queued signal from the watcher thread, so this executes
on the GUI thread exactly like a click on "Capture Tmp Reference".
"""
# Ignore a re-entrant press: the capture flow spins the event loop (stop/
# start run, dialogs), so a second queued press must not start a nested capture.
if self._control_button_busy:
self._log("GPIO control button press ignored: capture already in progress.")
return
self._control_button_busy = True
try:
self._log("GPIO control button pressed: capturing tmp reference.")
self._capture_tmp_reference()
finally:
self._control_button_busy = False
# The shared re-entrancy guard lives in _capture_tmp_reference, so this GPIO
# trigger and the GUI "Capture Tmp Reference" button are protected by one
# mechanism (a press during an in-progress capture is ignored there).
self._log("GPIO control button pressed: capturing tmp reference.")
self._capture_tmp_reference()
def _on_control_button_failed(self, message: str) -> None:
"""Log an unrecoverable watcher error reported from the background thread."""
@@ -469,8 +469,8 @@ class AppWindowPipelineMixin:
if collection is None:
break
self._pipeline_metrics.record("processing", int(collection.processing_duration_ns))
if record_result_history(self._result_history, collection):
latest = collection
record_result_history(self._result_history, collection)
latest = collection
return latest
def _pump_events_during_drain(self, pause_s: float) -> None:
@@ -43,7 +43,9 @@ class AppWindowTracePlotMixin:
details=f"{exc}\nExpected format: input:output,input:output",
once_key=f"pass_through_combo_filter_invalid_{text}",
)
return set()
# Fail open: an unparseable filter is ignored (all traces stay visible),
# not turned into an empty allow-set that silently hides every trace.
return None
def _configure_pass_through_magnitude_axis(self, plot: pg.PlotWidget) -> None:
"""Apply pass-through magnitude-axis autorange or fixed Y window."""
@@ -117,6 +117,13 @@ class AppWindowPreprocessMixin:
details=self._capture_state_details(),
)
return
# One shared re-entrancy guard for BOTH the GUI button and the GPIO trigger:
# this capture spins the Qt event loop (stop/start run, dialogs), so a second
# request from either source must not start a nested capture.
if self._control_button_busy:
self._log("Tmp reference capture already in progress; ignoring duplicate request.")
return
self._control_button_busy = True
pipeline_was_running = self._supervisor.is_running()
pipeline_was_paused = False
@@ -178,6 +185,7 @@ class AppWindowPreprocessMixin:
finally:
if pipeline_was_paused:
self._start_run()
self._control_button_busy = False
def _ensure_preprocess_dialog(self) -> PreprocessDialog:
"""Create preprocessing dialog lazily and wire its signals once."""
@@ -160,7 +160,7 @@ class AppWindowUiMixin:
self._status_label = QLabel("Status: idle", self._settings_panel)
self._status_label.setObjectName("statusLabel")
self._status_label.hide()
right_layout.addWidget(self._status_label)
self._history_label = QLabel("History: raw=0, preprocessed=0, results=0", self._settings_panel)
self._history_label.setObjectName("hintLabel")
@@ -25,7 +25,10 @@ def build_data_actions_group(owner) -> QGroupBox:
save_button = QPushButton("Save Dataset")
save_button.clicked.connect(owner._save_snapshot)
save_button.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Fixed)
save_vna_json_button = QPushButton("Save JSON")
save_vna_json_button = QPushButton("Save S21 JSON")
save_vna_json_button.setToolTip(
"Export one S21 VNA-history JSON per combo from the preprocessed stage (S11 is not included)."
)
save_vna_json_button.clicked.connect(owner._save_vna_history_json)
save_vna_json_button.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Fixed)
remove_last_button = QPushButton("Remove Last Measurement")