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():
|
def main():
|
||||||
"""Initializes and runs the application."""
|
"""Initializes and runs the application."""
|
||||||
|
import logging
|
||||||
|
logging.getLogger('matplotlib').setLevel(logging.WARNING)
|
||||||
|
|
||||||
app = MainView()
|
app = MainView()
|
||||||
|
|
||||||
# Setup the global logging system, connecting it to the GUI's main loop
|
# 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 = 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.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)
|
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")
|
log_frame_container = ttk.LabelFrame(v_pane, text="Logs")
|
||||||
v_pane.add(log_frame_container, weight=1)
|
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 = 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)
|
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):
|
def _draw_conn_status_indicator(self, connected: bool):
|
||||||
self.conn_status_canvas.delete("all")
|
self.conn_status_canvas.delete("all")
|
||||||
color = "#2ecc40" if connected else "#e74c3c" # green or red
|
color = "#2ecc40" if connected else "#e74c3c" # green or red
|
||||||
|
|||||||
@ -108,52 +108,72 @@ class PPIDisplay(ttk.Frame):
|
|||||||
|
|
||||||
def update_targets(self, targets: List[Target]):
|
def update_targets(self, targets: List[Target]):
|
||||||
"""
|
"""
|
||||||
Updates the positions of targets on the PPI display.
|
Aggiorna la posizione dei target sulla PPI e mostra l'ID accanto al punto. Tooltip con ID al passaggio del mouse.
|
||||||
|
|
||||||
Args:
|
|
||||||
targets: A list of Target objects to display.
|
|
||||||
"""
|
"""
|
||||||
# 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:
|
if targets:
|
||||||
self.active_targets = [t for t in targets if t.active]
|
self.active_targets = [t for t in targets if t.active]
|
||||||
|
|
||||||
# Clear previously drawn targets
|
# Rimuovi artisti precedenti
|
||||||
for artist in self.target_artists:
|
for artist in self.target_artists:
|
||||||
artist.remove()
|
artist.remove()
|
||||||
self.target_artists.clear()
|
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', []):
|
for target in getattr(self, 'active_targets', []):
|
||||||
# Target position in polar
|
|
||||||
r1 = target.range_nm
|
r1 = target.range_nm
|
||||||
th1 = np.deg2rad(target.azimuth_deg)
|
th1 = np.deg2rad(target.azimuth_deg)
|
||||||
|
# Punto del target
|
||||||
# Plot the target's center dot
|
dot, = self.ax.plot(th1, r1, 'o', markersize=5, color='red', picker=5)
|
||||||
dot, = self.ax.plot(th1, r1, 'o', markersize=5, color='red')
|
|
||||||
self.target_artists.append(dot)
|
self.target_artists.append(dot)
|
||||||
|
self._target_dots.append((dot, target))
|
||||||
|
|
||||||
# --- Calculate and plot heading vector ---
|
# Vettore heading
|
||||||
# Convert target polar to cartesian
|
|
||||||
x1 = r1 * np.sin(th1)
|
x1 = r1 * np.sin(th1)
|
||||||
y1 = r1 * np.cos(th1)
|
y1 = r1 * np.cos(th1)
|
||||||
|
|
||||||
# Calculate heading vector components
|
|
||||||
h_rad = np.deg2rad(target.heading_deg)
|
h_rad = np.deg2rad(target.heading_deg)
|
||||||
dx = vector_len * np.sin(h_rad)
|
dx = vector_len * np.sin(h_rad)
|
||||||
dy = vector_len * np.cos(h_rad)
|
dy = vector_len * np.cos(h_rad)
|
||||||
|
|
||||||
# Calculate end point of the vector in cartesian
|
|
||||||
x2, y2 = x1 + dx, y1 + dy
|
x2, y2 = x1 + dx, y1 + dy
|
||||||
|
|
||||||
# Convert end point back to polar
|
|
||||||
r2 = np.sqrt(x2**2 + y2**2)
|
r2 = np.sqrt(x2**2 + y2**2)
|
||||||
th2 = np.arctan2(x2, y2)
|
th2 = np.arctan2(x2, y2)
|
||||||
|
|
||||||
# Plot the heading line
|
|
||||||
line, = self.ax.plot([th1, th2], [r1, r2], color='red', linewidth=1.2)
|
line, = self.ax.plot([th1, th2], [r1, r2], color='red', linewidth=1.2)
|
||||||
self.target_artists.append(line)
|
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()
|
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."""
|
"""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")
|
super().__init__(master, text="Target List")
|
||||||
self.targets_cache = []
|
self.targets_cache = []
|
||||||
|
self.targets_changed_callback = targets_changed_callback
|
||||||
# --- Treeview for Targets ---
|
# --- Treeview for Targets ---
|
||||||
columns = ("id", "range", "az", "vel", "hdg", "alt")
|
columns = ("id", "range", "az", "vel", "hdg", "alt")
|
||||||
self.tree = ttk.Treeview(self, columns=columns, show="headings")
|
self.tree = ttk.Treeview(self, columns=columns, show="headings")
|
||||||
@ -72,6 +73,8 @@ class TargetListFrame(ttk.LabelFrame):
|
|||||||
if add_window.new_target:
|
if add_window.new_target:
|
||||||
self.targets_cache.append(add_window.new_target)
|
self.targets_cache.append(add_window.new_target)
|
||||||
self.update_target_list(self.targets_cache)
|
self.update_target_list(self.targets_cache)
|
||||||
|
if self.targets_changed_callback:
|
||||||
|
self.targets_changed_callback(self.targets_cache)
|
||||||
|
|
||||||
def _on_remove_click(self):
|
def _on_remove_click(self):
|
||||||
selected = self.tree.focus()
|
selected = self.tree.focus()
|
||||||
@ -93,6 +96,8 @@ class TargetListFrame(ttk.LabelFrame):
|
|||||||
# Rimuovi il target dalla lista
|
# Rimuovi il target dalla lista
|
||||||
self.targets_cache = [t for t in getattr(self, 'targets_cache', []) if t.target_id != target_id]
|
self.targets_cache = [t for t in getattr(self, 'targets_cache', []) if t.target_id != target_id]
|
||||||
self.update_target_list(self.targets_cache)
|
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à)
|
# Bind doppio click su una riga (usando identify_row per maggiore affidabilità)
|
||||||
self.tree.bind('<Double-1>', self._on_double_click)
|
self.tree.bind('<Double-1>', self._on_double_click)
|
||||||
@ -127,7 +132,8 @@ class TargetListFrame(ttk.LabelFrame):
|
|||||||
return
|
return
|
||||||
# Apri la finestra di modifica
|
# Apri la finestra di modifica
|
||||||
from .add_target_window import AddTargetWindow
|
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)
|
# Precompila i dati (tranne l'id)
|
||||||
edit_window.id_var.set(target_id)
|
edit_window.id_var.set(target_id)
|
||||||
edit_window.id_spinbox.config(state='disabled')
|
edit_window.id_spinbox.config(state='disabled')
|
||||||
@ -149,6 +155,8 @@ class TargetListFrame(ttk.LabelFrame):
|
|||||||
target.altitude_ft = edit_window.new_target.altitude_ft
|
target.altitude_ft = edit_window.new_target.altitude_ft
|
||||||
# Aggiorna la tabella
|
# Aggiorna la tabella
|
||||||
self.update_target_list(self.targets_cache)
|
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):
|
def _on_double_click(self, event):
|
||||||
# Usa identify_row per trovare la riga cliccata
|
# Usa identify_row per trovare la riga cliccata
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user