new GPR parameters and some UI fixes

This commit is contained in:
Ayzen
2026-04-07 12:55:26 +03:00
parent 4b78c2808d
commit 202993325d
27 changed files with 1494 additions and 168 deletions
@@ -77,7 +77,7 @@ class AppWindowUiMixin:
# Default view on startup is pass-through traces.
self._plot_stack.setCurrentWidget(self._trace_plots_container)
root_layout.addWidget(self._plot_stack, stretch=12)
root_layout.addWidget(self._plot_stack, stretch=11)
@staticmethod
def _create_plot_widget(*, background: str) -> pg.PlotWidget:
@@ -89,6 +89,7 @@ class AppWindowUiMixin:
# B-scan surface: one PlotWidget used as canvas for ImageItem heatmap.
self._bscan_plot = self._create_plot_widget(background="#0f141c")
self._bscan_plot.showGrid(x=True, y=True, alpha=0.2)
self._configure_bscan_plot_axes()
self._plot_stack.addWidget(self._bscan_plot)
def _build_trace_plot_page(self) -> None:
@@ -131,6 +132,7 @@ class AppWindowUiMixin:
"""Create GPR page in plot stack."""
self._gpr_plot = self._create_plot_widget(background="#0f141c")
self._gpr_plot.showGrid(x=True, y=True, alpha=0.2)
self._configure_gpr_plot_axes()
self._plot_stack.addWidget(self._gpr_plot)
def _build_settings_toggle(self, root_layout: QHBoxLayout) -> None:
@@ -142,7 +144,7 @@ class AppWindowUiMixin:
root_layout.addWidget(self._settings_toggle_button, stretch=0)
def _build_settings_panel(self, root_layout: QHBoxLayout, root: QWidget) -> None:
"""Build right settings panel with controls, status labels, and log."""
"""Build right settings panel with controls, history summary, and log."""
self._settings_panel = QWidget(root)
self._settings_panel.setMinimumWidth(610)
right_layout = QVBoxLayout(self._settings_panel)
@@ -151,6 +153,31 @@ class AppWindowUiMixin:
# Build log early so `_show_error()` can append text even during
# subsequent group construction if something fails.
self._log_panel = self._build_log_panel()
right_layout.addWidget(build_primary_actions_group(self), stretch=0)
right_layout.addWidget(self._build_settings_scroll(), stretch=1)
self._status_label = QLabel("Status: idle", self._settings_panel)
self._status_label.setObjectName("statusLabel")
self._status_label.hide()
self._history_label = QLabel("History: raw=0, preprocessed=0, results=0", self._settings_panel)
self._history_label.setObjectName("hintLabel")
right_layout.addWidget(self._history_label)
right_layout.addWidget(self._log_panel, stretch=0)
root_layout.addWidget(self._settings_panel, stretch=7)
def _build_log_panel(self) -> QWidget:
"""Build runtime log block with collapsible log body."""
self._log_panel_title = QLabel("Runtime Log", self._settings_panel)
self._log_panel_title.setObjectName("hintLabel")
self._log_toggle_button = QPushButton(self._settings_panel)
self._log_toggle_button.setObjectName("sectionToggleButton")
self._log_toggle_button.clicked.connect(lambda: self._toggle_log_panel())
self._log_box = QTextEdit(self._settings_panel)
self._log_box.setObjectName("runtimeLogBox")
self._log_box.setReadOnly(True)
@@ -158,19 +185,24 @@ class AppWindowUiMixin:
self._log_box.setMinimumHeight(170)
self._log_box.document().setMaximumBlockCount(1200)
right_layout.addWidget(build_primary_actions_group(self), stretch=0)
right_layout.addWidget(self._build_settings_scroll(), stretch=1)
panel = QWidget(self._settings_panel)
panel_layout = QVBoxLayout(panel)
panel_layout.setContentsMargins(0, 0, 0, 0)
panel_layout.setSpacing(6)
self._status_label = QLabel("Status: idle", self._settings_panel)
self._status_label.setObjectName("statusLabel")
right_layout.addWidget(self._status_label)
header_row = QWidget(panel)
header_layout = QHBoxLayout(header_row)
header_layout.setContentsMargins(0, 0, 0, 0)
header_layout.setSpacing(8)
header_layout.addWidget(self._log_panel_title)
header_layout.addStretch(1)
header_layout.addWidget(self._log_toggle_button)
self._history_label = QLabel("History: raw=0, preprocessed=0, results=0", self._settings_panel)
self._history_label.setObjectName("hintLabel")
right_layout.addWidget(self._history_label)
panel_layout.addWidget(header_row)
panel_layout.addWidget(self._log_box)
right_layout.addWidget(self._log_box, stretch=0)
root_layout.addWidget(self._settings_panel, stretch=7)
self._toggle_log_panel(visible=True)
return panel
def _build_settings_scroll(self) -> QScrollArea:
"""Build scroll area with all control groups in display order."""
@@ -178,7 +210,7 @@ class AppWindowUiMixin:
# remains usable on smaller screens and with future extra controls.
controls = QWidget(self._settings_panel)
controls_layout = QVBoxLayout(controls)
controls_layout.setContentsMargins(0, 0, 0, 0)
controls_layout.setContentsMargins(0, 0, 12, 0)
controls_layout.setSpacing(10)
for group in self._build_control_groups():
controls_layout.addWidget(group)
@@ -193,8 +225,8 @@ class AppWindowUiMixin:
def _build_control_groups(self) -> list[QGroupBox]:
"""Create all settings groups in top-to-bottom order."""
return [
build_switch_group(self),
build_data_actions_group(self),
build_switch_group(self),
build_preprocess_summary_group(self),
build_processing_group(self),
build_radar_group(self),
@@ -216,6 +248,19 @@ class AppWindowUiMixin:
self._settings_toggle_button.setText("<")
self._settings_toggle_button.setToolTip("Show settings panel")
def _toggle_log_panel(self, *, visible: bool | None = None) -> None:
"""Toggle runtime log body visibility or force a specific state."""
if visible is None:
visible = not self._log_box.isVisible()
self._log_box.setVisible(visible)
if visible:
self._log_toggle_button.setText("Collapse")
self._log_toggle_button.setToolTip("Hide runtime log entries")
else:
self._log_toggle_button.setText("Expand")
self._log_toggle_button.setToolTip("Show runtime log entries")
def _set_plot_mode(self, mode: str) -> None:
"""Switch visible plot page according to processing mode.