Files
radar_system/python_app/gui/main.py
T
2026-05-26 15:08:56 +03:00

71 lines
2.1 KiB
Python

"""Application entry point for the PyQt GUI."""
from __future__ import annotations
import os
from pathlib import Path
import signal
import sys
import pyqtgraph as pg
from PyQt6.QtCore import QTimer
from PyQt6.QtWidgets import QApplication
# Ensure imports are resolved when started as a script.
PROJECT_ROOT = Path(__file__).resolve().parents[2]
if str(PROJECT_ROOT) not in sys.path:
sys.path.insert(0, str(PROJECT_ROOT))
from python_app.gui.app_window import AppWindow
from python_app.gui.theme import apply_light_theme
def _is_headless() -> bool:
"""Return whether the launcher requested a non-interactive deployment."""
return os.environ.get("RADAR_SYSTEM_HEADLESS", "").strip().lower() in {
"1",
"true",
"yes",
"on",
}
def _install_unix_signal_handlers(app: QApplication, window: AppWindow) -> None:
"""Route SIGINT and SIGTERM through the Qt event loop into a clean shutdown.
`window.close()` runs `closeEvent`, which aborts any active capture and
shuts down managed C++ processes; only then does the Qt loop exit. A
short repeating timer keeps the Python interpreter pinned in the event
loop just long enough to deliver pending signals.
"""
def _request_shutdown(*_args: object) -> None:
window.close()
app.quit()
for sig in (signal.SIGINT, signal.SIGTERM):
signal.signal(sig, _request_shutdown)
keepalive_timer = QTimer(app)
keepalive_timer.setInterval(200)
keepalive_timer.timeout.connect(lambda: None)
keepalive_timer.start()
def main() -> int:
"""Run Qt event loop and show main radar control window."""
app = QApplication(sys.argv)
apply_light_theme(app)
# PyQtGraph foreground controls axis lines, tick text, labels, and titles.
pg.setConfigOptions(antialias=True, background="#ffffff", foreground="#ffffff")
window = AppWindow(PROJECT_ROOT)
if _is_headless():
_install_unix_signal_handlers(app, window)
else:
window.showMaximized()
return app.exec()
if __name__ == "__main__":
raise SystemExit(main())