modificato gestione messaggi in simulazione su status bar
This commit is contained in:
parent
b03777ae13
commit
b3db92e101
@ -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()
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user