Files
skyplot/sky_plot.py
T
jens f0d49a3a7c - added tabs
- added plot tab
2026-05-18 21:48:04 +02:00

190 lines
6.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env python3
"""
GNSS Sky Plot Viewer
Unterstützt UBX über serielle Schnittstelle UND TCP/IP (Ser2net).
TCP/IP-Verbindungen werden in einer persistenten LRU-Liste (max. 5) gespeichert.
"""
import sys
from PyQt5.QtWidgets import (
QApplication, QMainWindow, QWidget, QVBoxLayout,
QHBoxLayout, QLabel, QStatusBar, QSplitter, QTabWidget)
from PyQt5.QtCore import Qt
from connection_panel import ConnectionPanel
from gnss_thread import GnssReader
from sat_table import SatelliteTable
from sky_plot_widget import SkyPlotWidget
from plot_tab import PlotTab
# ---------------------------------------------------------------------------
# Hauptfenster
# ---------------------------------------------------------------------------
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("GNSS Sky Plot UBX | Seriell + TCP/IP")
self.resize(980, 680)
self.setStyleSheet("background-color: #12192b; color: #cccccc;")
self._reader = None
self._build_ui()
def _build_ui(self):
central = QWidget()
self.setCentralWidget(central)
root = QVBoxLayout(central)
root.setContentsMargins(8, 8, 8, 8)
# Haupt-Tabs
self._main_tabs = QTabWidget()
self._main_tabs.setStyleSheet("""
QTabBar::tab {
background: #1a3a5c;
color: #cccccc;
padding: 6px 20px;
border-radius: 3px;
}
QTabBar::tab:selected {
background: #2a5a8c;
color: #ffffff;
}
""")
# ── Tab 1: Verbindung ─────────────────────────────────────────────────
conn_tab = QWidget()
conn_layout = QVBoxLayout(conn_tab)
conn_layout.setContentsMargins(8, 8, 8, 8)
self._conn_panel = ConnectionPanel()
self._conn_panel.connect_requested.connect(self._connect)
self._conn_panel.disconnect_requested.connect(self._disconnect)
conn_layout.addWidget(self._conn_panel)
conn_layout.addStretch()
self._main_tabs.addTab(conn_tab, "🔌 Verbindung")
# ── Tab 2: Sky View ───────────────────────────────────────────────────
view_tab = QWidget()
view_layout = QVBoxLayout(view_tab)
view_layout.setContentsMargins(8, 8, 8, 8)
# ── Tab 3: Plot ───────────────────────────────────────────────────
self._plot_tab = PlotTab()
self._main_tabs.addTab(self._plot_tab, "📈 Plot")
# Satellitenanzahl
self._sat_label = QLabel("Satelliten: ")
self._sat_label.setAlignment(Qt.AlignRight | Qt.AlignVCenter)
self._sat_label.setStyleSheet("font-size: 13px; color: #7ab7d4;")
view_layout.addWidget(self._sat_label)
# Splitter: Sky Plot | Tabelle
splitter = QSplitter(Qt.Horizontal)
self._sky_plot = SkyPlotWidget()
self._table = SatelliteTable()
splitter.addWidget(self._sky_plot)
splitter.addWidget(self._table)
splitter.setSizes([540, 380])
view_layout.addWidget(splitter)
self._main_tabs.addTab(view_tab, "🛰 Sky View")
root.addWidget(self._main_tabs)
# Status Bar
self._status = QStatusBar()
self.setStatusBar(self._status)
self._status.showMessage("Nicht verbunden.")
def __build_ui(self):
central = QWidget()
self.setCentralWidget(central)
root = QVBoxLayout(central)
root.setContentsMargins(8, 8, 8, 8)
# Obere Leiste
top = QHBoxLayout()
self._conn_panel = ConnectionPanel()
self._conn_panel.connect_requested.connect(self._connect)
self._conn_panel.disconnect_requested.connect(self._disconnect)
top.addWidget(self._conn_panel)
self._sat_label = QLabel("Satelliten: ")
self._sat_label.setAlignment(Qt.AlignRight | Qt.AlignVCenter)
self._sat_label.setStyleSheet("font-size: 13px; color: #7ab7d4;")
top.addStretch()
top.addWidget(self._sat_label)
root.addLayout(top)
# Splitter: Sky Plot | Tabelle
splitter = QSplitter(Qt.Horizontal)
self._sky_plot = SkyPlotWidget()
self._table = SatelliteTable()
splitter.addWidget(self._sky_plot)
splitter.addWidget(self._table)
splitter.setSizes([540, 380])
root.addWidget(splitter)
self._status = QStatusBar()
self.setStatusBar(self._status)
self._status.showMessage("Nicht verbunden.")
def _connect(self, factory, label: str):
self._reader = GnssReader(factory)
self._reader.satellites_updated.connect(self._on_satellites)
self._reader.error_occurred.connect(self._on_error)
self._reader.connected.connect(
lambda msg: (
self._status.showMessage(f"{msg}: {label}"),
self._main_tabs.setCurrentIndex(1), # → Sky View
)
)
self._reader.start()
self._conn_panel.set_connected(True)
self._status.showMessage(f"Verbinde mit {label} …")
def __connect(self, factory, label: str):
self._reader = GnssReader(factory)
self._reader.satellites_updated.connect(self._on_satellites)
self._reader.error_occurred.connect(self._on_error)
self._reader.connected.connect(
lambda msg: self._status.showMessage(f"{msg}: {label}")
)
self._reader.start()
self._conn_panel.set_connected(True)
self._status.showMessage(f"Verbinde mit {label} …")
def _disconnect(self):
if self._reader:
self._reader.stop()
self._reader = None
self._conn_panel.set_connected(False)
self._status.showMessage("Verbindung getrennt.")
def _on_satellites(self, sats: list):
visible = [s for s in sats if s["elev"] >= 0]
used = sum(1 for s in sats if s["used"])
self._sat_label.setText(f"Satelliten: {len(visible)} sichtbar, {used} genutzt")
self._sky_plot.update_satellites(visible)
self._table.update_satellites(visible)
self._plot_tab.update_data(visible) # ← neu
def _on_error(self, msg: str):
self._status.showMessage(f"Fehler: {msg}")
self._disconnect()
def closeEvent(self, event):
self._disconnect()
super().closeEvent(event)
# ---------------------------------------------------------------------------
if __name__ == "__main__":
app = QApplication(sys.argv)
app.setStyle("Fusion")
win = MainWindow()
win.show()
sys.exit(app.exec_())