fix gui and button fuction
This commit is contained in:
parent
4797533386
commit
08aa827cd7
@ -23,6 +23,9 @@ from config import LOGGING_CONFIG
|
||||
|
||||
def main():
|
||||
"""Initializes and runs the application."""
|
||||
import logging
|
||||
logging.getLogger('matplotlib').setLevel(logging.WARNING)
|
||||
|
||||
app = MainView()
|
||||
|
||||
# Setup the global logging system, connecting it to the GUI's main loop
|
||||
|
||||
@ -77,14 +77,19 @@ class MainView(tk.Tk):
|
||||
self.scenario_controls = ScenarioControlsFrame(left_frame, load_scenario_command=self._on_load_scenario, save_as_command=self._on_save_scenario_as, update_command=self._on_update_scenario, delete_command=self._on_delete_scenario)
|
||||
self.scenario_controls.pack(fill=tk.X, expand=False, padx=5, pady=(5, 5))
|
||||
|
||||
self.target_list = TargetListFrame(left_frame)
|
||||
self.target_list = TargetListFrame(left_frame, targets_changed_callback=self._on_targets_changed)
|
||||
self.target_list.pack(fill=tk.BOTH, expand=True, padx=5)
|
||||
# I bottoni Add/Remove/Edit sono gestiti dal frame stesso
|
||||
|
||||
# --- Logs Frame ---
|
||||
log_frame_container = ttk.LabelFrame(v_pane, text="Logs")
|
||||
v_pane.add(log_frame_container, weight=1)
|
||||
self.log_text_widget = scrolledtext.ScrolledText(log_frame_container, state=tk.DISABLED, wrap=tk.WORD, font=("Consolas", 9))
|
||||
self.log_text_widget.pack(fill=tk.BOTH, expand=True, padx=5, pady=5)
|
||||
|
||||
def _on_targets_changed(self, targets):
|
||||
# Called by TargetListFrame when targets are changed
|
||||
self.ppi_widget.update_targets(targets)
|
||||
|
||||
def _draw_conn_status_indicator(self, connected: bool):
|
||||
self.conn_status_canvas.delete("all")
|
||||
color = "#2ecc40" if connected else "#e74c3c" # green or red
|
||||
|
||||
@ -108,52 +108,72 @@ class PPIDisplay(ttk.Frame):
|
||||
|
||||
def update_targets(self, targets: List[Target]):
|
||||
"""
|
||||
Updates the positions of targets on the PPI display.
|
||||
|
||||
Args:
|
||||
targets: A list of Target objects to display.
|
||||
Aggiorna la posizione dei target sulla PPI e mostra l'ID accanto al punto. Tooltip con ID al passaggio del mouse.
|
||||
"""
|
||||
# If an empty list is passed, it means we just want to redraw existing targets
|
||||
# (e.g., after a zoom change), not clear them.
|
||||
if targets:
|
||||
self.active_targets = [t for t in targets if t.active]
|
||||
|
||||
# Clear previously drawn targets
|
||||
# Rimuovi artisti precedenti
|
||||
for artist in self.target_artists:
|
||||
artist.remove()
|
||||
self.target_artists.clear()
|
||||
|
||||
vector_len = self.range_var.get() / 25 # Length of heading vector relative to current view
|
||||
# Rimuovi eventuali tooltips precedenti
|
||||
if hasattr(self, 'tooltips'):
|
||||
for tip in self.tooltips:
|
||||
tip.remove()
|
||||
self.tooltips = []
|
||||
|
||||
vector_len = self.range_var.get() / 25
|
||||
self._target_dots = []
|
||||
|
||||
for target in getattr(self, 'active_targets', []):
|
||||
# Target position in polar
|
||||
r1 = target.range_nm
|
||||
th1 = np.deg2rad(target.azimuth_deg)
|
||||
|
||||
# Plot the target's center dot
|
||||
dot, = self.ax.plot(th1, r1, 'o', markersize=5, color='red')
|
||||
# Punto del target
|
||||
dot, = self.ax.plot(th1, r1, 'o', markersize=5, color='red', picker=5)
|
||||
self.target_artists.append(dot)
|
||||
self._target_dots.append((dot, target))
|
||||
|
||||
# --- Calculate and plot heading vector ---
|
||||
# Convert target polar to cartesian
|
||||
# Vettore heading
|
||||
x1 = r1 * np.sin(th1)
|
||||
y1 = r1 * np.cos(th1)
|
||||
|
||||
# Calculate heading vector components
|
||||
h_rad = np.deg2rad(target.heading_deg)
|
||||
dx = vector_len * np.sin(h_rad)
|
||||
dy = vector_len * np.cos(h_rad)
|
||||
|
||||
# Calculate end point of the vector in cartesian
|
||||
x2, y2 = x1 + dx, y1 + dy
|
||||
|
||||
# Convert end point back to polar
|
||||
r2 = np.sqrt(x2**2 + y2**2)
|
||||
th2 = np.arctan2(x2, y2)
|
||||
|
||||
# Plot the heading line
|
||||
line, = self.ax.plot([th1, th2], [r1, r2], color='red', linewidth=1.2)
|
||||
self.target_artists.append(line)
|
||||
|
||||
# Redraw the canvas to show the changes
|
||||
# Gestione tooltip
|
||||
def on_motion(event):
|
||||
# Mostra hint se il mouse è vicino a un punto target
|
||||
if event.inaxes != self.ax:
|
||||
if hasattr(self, '_tooltip_label') and self._tooltip_label:
|
||||
self._tooltip_label.place_forget()
|
||||
self._tooltip_label = None
|
||||
return
|
||||
found = False
|
||||
for dot, target in self._target_dots:
|
||||
cont, _ = dot.contains(event)
|
||||
if cont:
|
||||
# Usa la posizione del mouse relativa al widget Tkinter
|
||||
self._show_tooltip(event.x + 10, event.y + 10, f"ID: {target.target_id}")
|
||||
found = True
|
||||
break
|
||||
if not found and hasattr(self, '_tooltip_label') and self._tooltip_label:
|
||||
self._tooltip_label.place_forget()
|
||||
self._tooltip_label = None
|
||||
|
||||
self.canvas.mpl_connect('motion_notify_event', on_motion)
|
||||
self._tooltip_label = None
|
||||
self.canvas.draw()
|
||||
|
||||
def _show_tooltip(self, x, y, text):
|
||||
# Mostra un tooltip Tkinter sopra la canvas, centrato sul punto target
|
||||
if self._tooltip_label:
|
||||
self._tooltip_label.place_forget()
|
||||
self._tooltip_label = tk.Label(self.canvas.get_tk_widget(), text=text, bg='yellow', fg='black', font=('Consolas', 9), relief='solid', borderwidth=1)
|
||||
self._tooltip_label.place(x=x, y=y)
|
||||
@ -15,9 +15,10 @@ class TargetListFrame(ttk.LabelFrame):
|
||||
|
||||
"""Frame for displaying and managing the list of targets."""
|
||||
|
||||
def __init__(self, master):
|
||||
def __init__(self, master, targets_changed_callback=None):
|
||||
super().__init__(master, text="Target List")
|
||||
self.targets_cache = []
|
||||
self.targets_changed_callback = targets_changed_callback
|
||||
# --- Treeview for Targets ---
|
||||
columns = ("id", "range", "az", "vel", "hdg", "alt")
|
||||
self.tree = ttk.Treeview(self, columns=columns, show="headings")
|
||||
@ -72,6 +73,8 @@ class TargetListFrame(ttk.LabelFrame):
|
||||
if add_window.new_target:
|
||||
self.targets_cache.append(add_window.new_target)
|
||||
self.update_target_list(self.targets_cache)
|
||||
if self.targets_changed_callback:
|
||||
self.targets_changed_callback(self.targets_cache)
|
||||
|
||||
def _on_remove_click(self):
|
||||
selected = self.tree.focus()
|
||||
@ -93,6 +96,8 @@ class TargetListFrame(ttk.LabelFrame):
|
||||
# Rimuovi il target dalla lista
|
||||
self.targets_cache = [t for t in getattr(self, 'targets_cache', []) if t.target_id != target_id]
|
||||
self.update_target_list(self.targets_cache)
|
||||
if self.targets_changed_callback:
|
||||
self.targets_changed_callback(self.targets_cache)
|
||||
|
||||
# Bind doppio click su una riga (usando identify_row per maggiore affidabilità)
|
||||
self.tree.bind('<Double-1>', self._on_double_click)
|
||||
@ -127,7 +132,8 @@ class TargetListFrame(ttk.LabelFrame):
|
||||
return
|
||||
# Apri la finestra di modifica
|
||||
from .add_target_window import AddTargetWindow
|
||||
edit_window = AddTargetWindow(self, existing_ids=[target_id])
|
||||
# Pass all other IDs except the one being edited
|
||||
edit_window = AddTargetWindow(self, existing_ids=[t.target_id for t in self.targets_cache if t.target_id != target_id])
|
||||
# Precompila i dati (tranne l'id)
|
||||
edit_window.id_var.set(target_id)
|
||||
edit_window.id_spinbox.config(state='disabled')
|
||||
@ -149,6 +155,8 @@ class TargetListFrame(ttk.LabelFrame):
|
||||
target.altitude_ft = edit_window.new_target.altitude_ft
|
||||
# Aggiorna la tabella
|
||||
self.update_target_list(self.targets_cache)
|
||||
if self.targets_changed_callback:
|
||||
self.targets_changed_callback(self.targets_cache)
|
||||
|
||||
def _on_double_click(self, event):
|
||||
# Usa identify_row per trovare la riga cliccata
|
||||
|
||||
Loading…
Reference in New Issue
Block a user