Files
OBD2-Simulator/app/gui/dashboard.py

66 lines
2.4 KiB
Python

# app/gui/dashboard.py
from __future__ import annotations
import tkinter as tk
from tkinter import ttk
class DashboardView:
def __init__(self, parent, sim, refresh_ms: int = 250):
self.sim = sim
self.frame = ttk.LabelFrame(parent, text="Dashboard", padding=6)
self.refresh_ms = refresh_ms
cols = ("label", "value", "unit", "key", "module")
self.tree = ttk.Treeview(self.frame, columns=cols, show="headings")
for c, w in zip(cols, (160, 80, 40, 160, 80)):
self.tree.heading(c, text=c.capitalize())
self.tree.column(c, width=w, anchor="w")
self.tree.grid(row=0, column=0, sticky="nsew")
sb_y = ttk.Scrollbar(self.frame, orient="vertical", command=self.tree.yview)
self.tree.configure(yscrollcommand=sb_y.set); sb_y.grid(row=0, column=1, sticky="ns")
self.frame.columnconfigure(0, weight=1)
self.frame.rowconfigure(0, weight=1)
self._rows = {}
self._tick()
def _tick(self):
snap = self.sim.v.dashboard_snapshot()
specs = snap.get("specs", {})
values = snap.get("values", {})
# sort by priority then label
ordered = sorted(specs.values(), key=lambda s: (s.get("priority", 100), s.get("label", s["key"])))
seen_keys = set()
for spec in ordered:
k = spec["key"]; seen_keys.add(k)
label = spec.get("label", k)
unit = spec.get("unit", "") or ""
fmt = spec.get("fmt")
src = spec.get("source", "")
val = values.get(k, "")
if fmt and isinstance(val, (int, float)):
try:
val = format(val, fmt)
except Exception:
pass
row_id = self._rows.get(k)
row_vals = (label, val, unit, k, src)
if row_id is None:
row_id = self.tree.insert("", "end", values=row_vals)
self._rows[k] = row_id
else:
self.tree.item(row_id, values=row_vals)
# delete rows that disappeared
for k, rid in list(self._rows.items()):
if k not in seen_keys:
try: self.tree.delete(rid)
except Exception: pass
self._rows.pop(k, None)
try:
self.frame.after(self.refresh_ms, self._tick)
except tk.TclError:
pass