Rework radar system

This commit is contained in:
Ayzen
2026-10-06 12:32:26 +03:00
parent 552cdc688a
commit 5bb86b7165
299 changed files with 13537 additions and 27763 deletions
@@ -0,0 +1,165 @@
"""Typed section widgets and the scalar Qt boundary shared by GUI settings."""
from collections.abc import Callable
from dataclasses import dataclass, field
from typing import TypeAlias, TypeVar
from PyQt6.QtWidgets import (
QCheckBox, QComboBox, QDoubleSpinBox, QGroupBox, QLineEdit, QPlainTextEdit,
QSpinBox, QWidget, QLabel, QPushButton, QStackedWidget,
)
from python_app.gui.antenna_geometry_editor import AntennaGeometryEditor
from python_app.models.setting_fields import Scalar
ScalarWidget: TypeAlias = QLineEdit | QPlainTextEdit | QComboBox | QCheckBox | QSpinBox | QDoubleSpinBox
SettingWidget: TypeAlias = ScalarWidget | AntennaGeometryEditor
_Widget = TypeVar("_Widget", bound=SettingWidget)
@dataclass(slots=True)
class SectionView:
group: QGroupBox
fields: dict[str, SettingWidget] = field(default_factory=dict)
def add(self, name: str, widget: _Widget) -> _Widget:
self.fields[name] = widget
return widget
@dataclass(slots=True, kw_only=True)
class PreprocessView(SectionView):
labels: dict[str, QLabel]
@dataclass(slots=True, kw_only=True)
class PrimaryView(SectionView):
start: QPushButton
single_capture: QPushButton
stop: QPushButton
apply_radar: QPushButton
load: QPushButton
save: QPushButton
preprocess: QPushButton
clear: QPushButton
@dataclass(slots=True, kw_only=True)
class DataView(SectionView):
save: QPushButton
save_json: QPushButton
remove_last: QPushButton
capture_tmp: QPushButton
record: QPushButton
browse: QPushButton
save_path: QLineEdit
save_name: QLineEdit
record_count: QSpinBox
@dataclass(slots=True, kw_only=True)
class SwitchView(SectionView):
select_text: QPushButton
select_single: QPushButton
combos: QLineEdit
single_input: QLineEdit
single_output: QLineEdit
display_combo: QComboBox
next_combo: QPushButton
@dataclass(slots=True, kw_only=True)
class ProcessingView(SectionView):
mode: QComboBox
pages: QStackedWidget
geometry_page: QWidget
geometries: tuple[AntennaGeometryEditor, AntennaGeometryEditor]
fixed_y: QCheckBox
y_bounds: tuple[QDoubleSpinBox, QDoubleSpinBox]
speed_controls: tuple[tuple[QCheckBox, QDoubleSpinBox], ...]
trace_controls: tuple[ScalarWidget, ...]
visual_controls: tuple[ScalarWidget, ...]
locator_controls: tuple[ScalarWidget, ...]
frequency_controls: tuple[QDoubleSpinBox, ...]
@dataclass(slots=True, kw_only=True)
class RadarView(SectionView):
sweep_edits: tuple[QLineEdit, ...]
sweep_labels: tuple[QLabel, ...]
limits_hint: QLabel
vna_panel: QWidget
adc_panel: QWidget
optical_enabled: QCheckBox
optical_mode: QComboBox
optical_common: tuple[ScalarWidget, ...]
optical_manual: tuple[ScalarWidget, ...]
optical_variation: tuple[ScalarWidget, ...]
manual_panel: QWidget
variation_panel: QWidget
def read_setting(widget: ScalarWidget) -> Scalar:
if isinstance(widget, QCheckBox):
return widget.isChecked()
if isinstance(widget, (QSpinBox, QDoubleSpinBox)):
return widget.value()
if isinstance(widget, QComboBox):
return widget.currentText()
if isinstance(widget, QPlainTextEdit):
return widget.toPlainText()
return widget.text()
def write_setting(widget: ScalarWidget, value: Scalar) -> None:
if isinstance(widget, QCheckBox):
widget.setChecked(bool(value))
elif isinstance(widget, QSpinBox):
widget.setValue(int(value))
elif isinstance(widget, QDoubleSpinBox):
widget.setValue(float(value))
elif isinstance(widget, QComboBox):
text = str(value)
index = widget.findText(text)
if index < 0:
widget.addItem(text)
index = widget.count() - 1
widget.setCurrentIndex(index)
elif isinstance(widget, QPlainTextEdit):
widget.setPlainText(str(value))
else:
widget.setText(str(value))
def connect_setting(widget: ScalarWidget, callback: Callable[..., object]) -> None:
if isinstance(widget, QCheckBox):
signal = widget.toggled
elif isinstance(widget, (QSpinBox, QDoubleSpinBox)):
signal = widget.valueChanged
elif isinstance(widget, QComboBox):
signal = widget.currentTextChanged
elif isinstance(widget, QPlainTextEdit):
signal = widget.textChanged
else:
signal = widget.editingFinished
signal.connect(callback)
def double_spin(minimum: float, maximum: float, decimals: int, step: float) -> QDoubleSpinBox:
widget = QDoubleSpinBox()
widget.setDecimals(decimals)
widget.setRange(minimum, maximum)
widget.setSingleStep(step)
return widget
def integer_spin(minimum: int, maximum: int) -> QSpinBox:
widget = QSpinBox()
widget.setRange(minimum, maximum)
return widget
def choice(options: list[str]) -> QComboBox:
widget = QComboBox()
widget.addItems(options)
return widget