Skip to content

Commit 140c75e

Browse files
minor fixes
- fixed the visualization window event handling by removing the nested mainloop() from VizView.show(), which previously opened a second Tk event loop for a Toplevel window. - Fixed the startup warning scheduling in mplace.py so _show_startup_warnings is passed to after() as a callback instead of being executed immediately. - Fixed a UI lock issue in the MiniZinc workflow where cancelling layout export format selection could leave the main window locked. - Fixed recent-file handling so opening a file from the Recent menu no longer re-adds the same file unnecessarily. - Improved cleanup of visualization resources by removing the ineffective local del canvas pattern and relying on explicit widget and figure teardown instead. - Improved consistency of the visualization window lifecycle by using normal Toplevel window behaviour instead of a second application loop. - Cleaned up small documentation inconsistencies
1 parent f80634e commit 140c75e

6 files changed

Lines changed: 12 additions & 12 deletions

File tree

controllers/minizinc_controller.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ def extract_csv_from_output(self, output: str) -> List[str]:
167167
raise ValueError(f"Could not extract CSV from output: {e}") from e
168168

169169
def get_timeout(self, use_compd: bool) -> Optional[int]:
170-
"""Return timeout in seconds from a MiniZinc .mpc file, or None if absent/unreadable."""
170+
"""Return timeout in seconds for the selected model."""
171171
if use_compd:
172172
return self._parse_timeout_s(self.app_config.compd_mpc_path)
173173
else:

models/application_state.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ class ApplicationState:
5757
# Plate configuration
5858
num_rows: str = PlateDefaults.ROWS
5959
num_cols: str = PlateDefaults.COLS
60-
control_names: str = '[]'
60+
control_names: str = PlateDefaults.CONTROL_NAMES
6161

6262
# Model selection
6363
use_compd: bool = False

mplace.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
from models.constants import PathsIni, Messages
4444

4545

46-
logger = logging.getLogger(__name__)
46+
logger = logging.getLogger(__name__)
4747

4848
def setup_logging() -> None:
4949
"""Configure application-wide logging."""
@@ -226,7 +226,7 @@ def run(self) -> None:
226226
logger.info("Starting MPLACE application main loop")
227227

228228
# Display startup warnings for missing configurations
229-
self.root.after(1, self._show_startup_warnings())
229+
self.root.after(1, self._show_startup_warnings)
230230

231231
self.views['main'].show()
232232

views/dzn_view.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
# Pure view layer - handles only UI display and user input.
1818
#
1919
# Authors: Ramiz GINDULLIN (ramiz.gindullin@it.uu.se)
20-
# Version: 1.3.0
20+
# Version: 1.3.1
2121
# Last Revision: March 2026
2222
#
2323

@@ -365,6 +365,7 @@ def _on_close(self) -> None:
365365

366366
def show(self) -> None:
367367
"""Show the DZN generation window."""
368+
self.reset_to_defaults()
368369
self.window.deiconify()
369370
self.window.grab_set()
370371

views/main_view.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,6 @@ def _apply_config_defaults(self) -> None:
202202
- Auto-selects a valid model if current selection is unavailable
203203
204204
Called from:
205-
- __init__() during startup
206205
- _set_program_state_to_default() to reapply after clearing state
207206
"""
208207
logger.info("Applying config defaults")
@@ -442,6 +441,8 @@ def _poll_mzn_result(self, model_name: str, dzn_path: str, original_text: str) -
442441
if not chosen_format:
443442
self.label_csv_loaded.config(text=original_text)
444443
logger.info("User cancelled format selection")
444+
self.unlock()
445+
self.root.focus_force()
445446
return
446447

447448
# Save in chosen format
@@ -542,10 +543,8 @@ def _open_recent_file(self, path: str, is_dzn: bool) -> None:
542543
self.root.focus_force()
543544
return
544545
self._update_run_minizinc_button_state()
545-
self._add_to_recent(path, True)
546546
else:
547547
self._load_csv_into_ui(path)
548-
self._add_to_recent(path, False)
549548
self.root.focus_force()
550549

551550
def _refresh_recent_menus(self) -> None:

views/viz_view.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
# Pure view layer - handles only UI display and matplotlib visualization.
1818
#
1919
# Authors: Ramiz GINDULLIN (ramiz.gindullin@it.uu.se)
20-
# Version: 1.3.0
20+
# Version: 1.3.1
2121
# Last Revision: March 2026
2222
#
2323

@@ -155,7 +155,7 @@ def show(
155155
self.window.geometry(f'+{x}+{y}')
156156
logger.debug("Entering visualization window mainloop")
157157

158-
self.window.mainloop()
158+
self.parent.wait_window(self.window)
159159

160160
except Exception as e:
161161
logger.error(f"Visualization error: {e}")
@@ -477,7 +477,6 @@ def _cleanup_and_close(self) -> None:
477477
finally:
478478
if self.window:
479479
logger.info("Visualization window closed")
480-
self.window.quit()
481480
self.window.destroy()
482481
self.window = None
483482
self.parent.focus_force()
@@ -494,8 +493,9 @@ def _cleanup_canvas_widgets(self, widget: tk.Misc) -> None:
494493
canvas = widget.canvas_ref
495494
fig = canvas.figure
496495
canvas.get_tk_widget().destroy()
496+
canvas.get_renderer()
497497
pyplot.close(fig)
498-
del canvas
498+
del widget.canvas_ref
499499
logger.debug("Canvas cleaned up")
500500
except (AttributeError, tk.TclError):
501501
pass

0 commit comments

Comments
 (0)