modificato gestione messaggi in simulazione su status bar

This commit is contained in:
VALLONGOL 2025-11-04 08:36:22 +01:00
parent b03777ae13
commit b3db92e101

View File

@ -619,30 +619,41 @@ class MainView(tk.Tk):
# Id used by show_status_message scheduling
self._status_after_id = None
def show_status_message(self, text: str, timeout_ms: int = 3000):
"""Show a transient status message in the main status bar.
def show_status_message(self, text: str, timeout_ms: int | None = 3000):
"""Show a status message in the main status bar.
If another message is scheduled to clear, cancel it and schedule the
new message to be cleared after timeout_ms.
If timeout_ms is None the message is persistent until explicitly
cleared or replaced. Otherwise the message will be cleared back to
"Ready" after timeout_ms milliseconds.
"""
try:
# Cancel previous scheduled clear if any
try:
if self._status_after_id is not None:
self.after_cancel(self._status_after_id)
self._status_after_id = None
except Exception:
pass
# Set message
self.status_var.set(text)
# Schedule clear back to Ready
def _clear():
try:
self.status_var.set("Ready")
except Exception:
pass
# Schedule clear back to Ready if timeout provided
if timeout_ms is not None:
def _clear():
try:
self.status_var.set("Ready")
except Exception:
pass
self._status_after_id = self.after(timeout_ms, _clear)
try:
self._status_after_id = self.after(timeout_ms, _clear)
except Exception:
# If scheduling fails, log and leave message as-is
try:
self.logger.exception("Failed to schedule status clear")
except Exception:
pass
except Exception:
# As a fallback, log the status
try:
@ -650,6 +661,28 @@ class MainView(tk.Tk):
except Exception:
pass
def clear_status_message(self):
"""Clear status to the default 'Ready' and cancel any pending clears."""
try:
try:
if self._status_after_id is not None:
self.after_cancel(self._status_after_id)
except Exception:
pass
try:
self._status_after_id = None
except Exception:
pass
try:
self.status_var.set("Ready")
except Exception:
pass
except Exception:
try:
self.logger.exception("Failed to clear status message")
except Exception:
pass
def _draw_status_indicator(self, canvas, color):
canvas.delete("all")
canvas.create_oval(2, 2, 14, 14, fill=color, outline="black")
@ -934,9 +967,14 @@ class MainView(tk.Tk):
except Exception:
pass
return
self._start_in_progress_main = True
try:
# Show a persistent 'starting' message while the controller/engine prepares
try:
self.show_status_message("Starting simulation...", timeout_ms=None)
except Exception:
pass
# Delegate to SimulationController if available
try:
if hasattr(self, "simulation_controller") and self.simulation_controller:
@ -950,6 +988,11 @@ class MainView(tk.Tk):
# If controller is not present or failed, attempt no-op fallback
try:
messagebox.showerror("Start Error", "Unable to start simulation (controller unavailable).")
# If start failed, clear the starting message so the status bar isn't stuck
try:
self.clear_status_message()
except Exception:
pass
except Exception:
pass
finally:
@ -978,25 +1021,65 @@ class MainView(tk.Tk):
def _on_simulation_finished(self):
try:
if hasattr(self, "simulation_controller") and self.simulation_controller:
return self.simulation_controller.on_simulation_finished(self)
try:
result = self.simulation_controller.on_simulation_finished(self)
except Exception:
result = None
else:
result = None
except Exception:
try:
self.logger.exception("SimulationController on_finished failed; falling back to inline finished handler.")
except Exception:
pass
result = None
# Ensure UI reflects finished state regardless of controller handling
try:
self.logger.error("Unable to handle simulation finished (controller unavailable).")
# Mark simulation as not running
try:
self.is_simulation_running.set(False)
except Exception:
pass
# Show a short transient message informing the user
try:
self.show_status_message("Simulation finished", timeout_ms=5000)
except Exception:
pass
except Exception:
pass
try:
self.logger.error("Unable to handle simulation finished (controller unavailable).")
except Exception:
pass
return result
def _on_reset_simulation(self):
self.logger.info("Resetting scenario to initial state.")
# Show a brief 'starting' message during the reset phase so users
# see that a reset/action is in progress (matches requested UX).
try:
self.show_status_message("Starting simulation...", timeout_ms=1500)
except Exception:
pass
if self.is_simulation_running.get():
self._on_stop_simulation()
self.scenario.reset_simulation()
self._update_all_views()
# After reset complete, clear or set Ready so the status bar does not
# remain stuck on 'Starting simulation...'
try:
self.show_status_message("Ready", timeout_ms=1500)
except Exception:
try:
self.clear_status_message()
except Exception:
pass
def _process_gui_queue(self):
"""
Processes a batch of updates from the GUI queue to keep the UI responsive
@ -1668,6 +1751,22 @@ class MainView(tk.Tk):
self.simulation_engine is not None and self.simulation_engine.is_running()
)
# Transition: started -> set running status
if (not sim_was_running) and sim_is_running_now:
try:
# Mark internal flag and show persistent running message
try:
self.is_simulation_running.set(True)
except Exception:
pass
try:
self.show_status_message("Simulation running", timeout_ms=None)
except Exception:
pass
except Exception:
pass
# Transition: stopped
if sim_was_running and not sim_is_running_now:
self._on_simulation_finished()