fix: tag_config for CTkTextbox + auto-save on file selection

- StatusDisplay: use tag_config (not tag_configure) for CTkTextbox
- FileSelector callbacks now trigger _auto_save_config() so that
  file path changes are persisted immediately to config.yaml
- This fixes the issue where UI file path changes weren't picked up
  by subsequent step executions
This commit is contained in:
2026-06-12 10:20:07 +08:00
parent a196211708
commit e2e1fdd2a0
2 changed files with 33 additions and 2 deletions
+31
View File
@@ -247,6 +247,23 @@ class MainWindow(ctk.CTk):
setattr(self._config, attr, self._config._relative_path(abs_path)) setattr(self._config, attr, self._config._relative_path(abs_path))
self._config.erase_all = self._erase_cb_var.get() self._config.erase_all = self._erase_cb_var.get()
def _auto_save_config(self) -> None:
"""Auto-save config to disk after UI changes.
Ensures that changes made in the UI (file paths, IP, etc.)
are persisted immediately so that _reload_config() picks them
up on the next step execution.
"""
if not self._config:
return
self._sync_config_from_ui()
user_config_path = self._get_user_config_path()
self._config._config_path = user_config_path
try:
self._config.save()
except Exception:
pass # Silently fail — user can manually save
def _save_config(self) -> None: def _save_config(self) -> None:
"""Save current configuration to user config file (config.yaml). """Save current configuration to user config file (config.yaml).
@@ -293,6 +310,15 @@ class MainWindow(ctk.CTk):
if self._config: if self._config:
self._config.zynq_ip = self._ip_string_var.get() self._config.zynq_ip = self._ip_string_var.get()
def _on_file_selected(self, path: str) -> None:
"""Handle file selection — sync and auto-save to disk.
When the user selects a file via the browse dialog, immediately
sync the path to the Config object and persist it to YAML so
that subsequent step executions pick up the new value.
"""
self._auto_save_config()
# ── UI Construction ──────────────────────────────────────── # ── UI Construction ────────────────────────────────────────
def _build_ui(self) -> None: def _build_ui(self) -> None:
@@ -558,6 +584,7 @@ class MainWindow(ctk.CTk):
panel, panel,
label_text="FSBL ELF (.elf):", label_text="FSBL ELF (.elf):",
file_types=[("ELF files", "*.elf"), ("All files", "*")], file_types=[("ELF files", "*.elf"), ("All files", "*")],
callback=self._on_file_selected,
) )
if self._config.fsbl_elf_path: if self._config.fsbl_elf_path:
resolved = self._config.resolve_path(self._config.fsbl_elf_path) resolved = self._config.resolve_path(self._config.fsbl_elf_path)
@@ -570,6 +597,7 @@ class MainWindow(ctk.CTk):
panel, panel,
label_text="Bootloader BIT (.bit):", label_text="Bootloader BIT (.bit):",
file_types=[("BIT files", "*.bit"), ("All files", "*")], file_types=[("BIT files", "*.bit"), ("All files", "*")],
callback=self._on_file_selected,
) )
if self._config.bootloader_bit_path: if self._config.bootloader_bit_path:
resolved = self._config.resolve_path(self._config.bootloader_bit_path) resolved = self._config.resolve_path(self._config.bootloader_bit_path)
@@ -582,6 +610,7 @@ class MainWindow(ctk.CTk):
panel, panel,
label_text="Bootloader ELF (.elf):", label_text="Bootloader ELF (.elf):",
file_types=[("ELF files", "*.elf"), ("All files", "*")], file_types=[("ELF files", "*.elf"), ("All files", "*")],
callback=self._on_file_selected,
) )
if self._config.bootloader_elf_path: if self._config.bootloader_elf_path:
resolved = self._config.resolve_path(self._config.bootloader_elf_path) resolved = self._config.resolve_path(self._config.bootloader_elf_path)
@@ -594,6 +623,7 @@ class MainWindow(ctk.CTk):
panel, panel,
label_text="Bootloader BIN (.bin):", label_text="Bootloader BIN (.bin):",
file_types=[("BIN files", "*.bin"), ("All files", "*")], file_types=[("BIN files", "*.bin"), ("All files", "*")],
callback=self._on_file_selected,
) )
if self._config.bootloader_bin_path: if self._config.bootloader_bin_path:
resolved = self._config.resolve_path(self._config.bootloader_bin_path) resolved = self._config.resolve_path(self._config.bootloader_bin_path)
@@ -628,6 +658,7 @@ class MainWindow(ctk.CTk):
panel, panel,
label_text="Firmware BIN (.bin):", label_text="Firmware BIN (.bin):",
file_types=[("BIN files", "*.bin"), ("All files", "*")], file_types=[("BIN files", "*.bin"), ("All files", "*")],
callback=self._on_file_selected,
) )
if self._config.firmware_bin_path: if self._config.firmware_bin_path:
resolved = self._config.resolve_path(self._config.firmware_bin_path) resolved = self._config.resolve_path(self._config.firmware_bin_path)
+2 -2
View File
@@ -489,8 +489,8 @@ class StatusDisplay(ctk.CTkFrame):
color = colors.get(status, INFO_COLOR) color = colors.get(status, INFO_COLOR)
self._status_text.insert("1.0", message) self._status_text.insert("1.0", message)
# Tag the entire text with the color # Tag the entire text with the color (CTkTextbox uses tag_config)
self._status_text.tag_configure("status", foreground=color) self._status_text.tag_config("status", foreground=color)
self._status_text.tag_add("status", "1.0", "end") self._status_text.tag_add("status", "1.0", "end")
self._status_text.configure(state="disabled") self._status_text.configure(state="disabled")