added data saving feature

This commit is contained in:
Ayzen
2026-06-23 12:19:31 +03:00
parent 716fd0b07a
commit 8db14b9482
20 changed files with 1192 additions and 63 deletions
+25
View File
@@ -25,6 +25,7 @@ from python_app.gui.controllers.app_window_config_mixin import AppWindowConfigMi
from python_app.gui.controllers.app_window_control_button_mixin import AppWindowControlButtonMixin
from python_app.gui.controllers.app_window_pipeline_mixin import AppWindowPipelineMixin
from python_app.gui.controllers.app_window_plot_mixin import AppWindowPlotMixin
from python_app.gui.controllers.app_window_recording_mixin import AppWindowRecordingMixin
from python_app.gui.controllers.app_window_preprocess_mixin import AppWindowPreprocessMixin
from python_app.gui.controllers.app_window_snapshot_mixin import AppWindowSnapshotMixin
from python_app.gui.controllers.app_window_ui_mixin import AppWindowUiMixin
@@ -96,6 +97,7 @@ class AppWindow(
AppWindowPlotMixin,
AppWindowPipelineMixin,
AppWindowSnapshotMixin,
AppWindowRecordingMixin,
AppWindowControlButtonMixin,
AppWindowWebMixin,
QMainWindow,
@@ -114,6 +116,7 @@ class AppWindow(
self._init_preprocess_state()
self._init_capture_state()
self._init_history_state()
self._init_recording_state()
self._init_runtime_limits()
self._init_polling_timer()
self._init_control_button_state()
@@ -676,9 +679,27 @@ class AppWindow(
return max(0, int(raw_value))
return 0
def _capture_web_action_error(self, message: str) -> bool:
"""Record the first error of an in-flight web action so the browser can show it.
Returns ``True`` if a web-triggered action is currently running (see
``AppWindowWebMixin._run_web_action``). Callers use that to skip the blocking
desktop modal for web errors — the browser shows the message instead, and the
operator at the browser must not have to dismiss a popup on the (often headless)
host before the HTTP response returns. Desktop-only errors are unaffected.
"""
capture = getattr(self, "_web_action_error_capture", None)
if capture is None:
return False
if not capture:
capture.append(message)
return True
def _show_error(self, message: str, *, details: str | None = None) -> None:
"""Log and present an error in a modal dialog with optional detail text."""
self._log_error(message, details=details)
if self._capture_web_action_error(message):
return # web-triggered: surfaced to the browser; no blocking desktop modal
if self._is_truthy_env("RADAR_SYSTEM_HEADLESS"):
return
dialog = QMessageBox(self)
@@ -692,6 +713,8 @@ class AppWindow(
def _show_exception(self, context: str, exc: Exception) -> None:
"""Log full exception details and show modal dialog with expandable traceback."""
message, details = self._log_exception(context, exc, level="ERROR")
if self._capture_web_action_error(message):
return # web-triggered: surfaced to the browser; no blocking desktop modal
if self._is_truthy_env("RADAR_SYSTEM_HEADLESS"):
return
dialog = QMessageBox(self)
@@ -717,6 +740,8 @@ class AppWindow(
try:
# 0) Stop the web server first so a late request cannot start work.
self._shutdown_web_ui()
# 0) Stop the disk-recording writer thread so it is not orphaned.
self._shutdown_recording()
# 0) Stop the GPIO button watcher so a late press cannot start work.
self._stop_control_button_watcher()
self._resume_pipeline_after_capture = False