UartMonitorWindow now accepts on_log callback. When boot info
(IP, version) is parsed from serial output, it:
- Appears in the UART window's own log (prefix [UART])
- Forwards to main window's log panel via on_log callback
- Unified [UART] prefix across both windows (was [BOOT] in
UART window, [UART] Boot detected: in main log)
Flow execution's _start_uart_monitor() now checks if a UART window
is already monitoring before starting its own UartMonitor instance.
This prevents two UartMonitor threads from fighting over the same
serial port.
Changes:
- UartMonitorWindow: add is_monitoring property
- MainWindow._uart_window: store reference to open UART window
- _start_uart_monitor(): skip if UART window already monitoring
- _on_close(): destroy UART window on main window close
_on_open_success(): directly call _on_start() instead of just
enabling the button. User no longer needs to click Start —
monitoring begins automatically when the port is available.
Start/Stop buttons remain for manual control.
CTkToplevel grab_set() fails when called before the window is
fully realized on screen. Defer to after(50ms) so the window
has time to become viewable.
Replace 'Read Serial' button with 'Open UART' that opens a new
UART Monitor window (CTkToplevel) with:
- Title bar with status indicator (● connecting/ready/monitoring/error)
- Port info display + Start/Stop/Clear buttons
- Large scrollable log area (CTkTextbox) with monospace font
- Auto-scroll to bottom, line counter in status bar
- Boot info parsing (IP, version) shown as [BOOT] prefix
- Background serial monitoring via UartMonitor class
UART unavailable handling:
- On init, tries to open serial port in background thread
- If port can't open → shows 'UART 不可用' state with error message
- If port opens → shows 'Ready', user clicks Start to begin monitoring
Window features:
- Modal (grab_set) — focus stays on monitor window
- Clean up UartMonitor on close (WM_DELETE_WINDOW handler)
- Thread-safe UI updates via after(0, ...)
- Reuses existing UartMonitor from serial_monitor.py
1. SubStepFrame defaults to expanded (▼), not collapsed
2. erase_all checkbox has command=_on_erase_toggle → immediate config update
3. _deferred_init runs _check_vitis/_refresh_ports in background thread
Fixes UI freeze during startup (subprocess.run for tool versions)
4. Sub-step colors now match StepHeader:
- pending: gray ACCENT_PENDING (#888888)
- running: blue CIRCLE_RUNNING (#0078D4) with pulse animation
- complete: green ACCENT_COMPLETE (#107C10)
- error: red ACCENT_ERROR (#D13438)
- Running sub-step pulses between light/dark blue like StepHeader
SubStepFrame now uses default CustomTkinter label colors (white
in dark mode, black in light mode) instead of manually set
CIRCLE_*/ACCENT_* colors that were unreadable on dark backgrounds.
Simplified grid layout — no nested sub-frames.
- Fix 6 overlapping widget bugs in StepHeader (title/desc, btn/icon,
run/rerun) with proper 5-column grid layout
- Merge run/rerun buttons into single _action_btn with state-driven text
- Fix DARK_CARD NameError (undefined import → STEP_CARD_BG)
- Replace fragile vertical connector lines with full-width dividers
- Add panel.grid_columnconfigure(0, weight=1) for horizontal scaling
- Unify button text across all states (▶ pending/disabled, ↻ retry)
- Tighten padding and reduce whitespace between steps
- Replace Segoe UI with Roboto for cross-platform compatibility
- Increase font sizes for better readability (9→11, 11→12, 14→15)
- Update dark theme to VS Code-like colors (#1E1E1E bg)
- Brighten accent colors and improve contrast ratios
- Fix StepHeader: number circle background, status icon positioning
- Enlarge accent bar (4→5px) and buttons (28→32px)
- Simplify status text (Completed → Done)
- Improve connector line sizing and alignment