Lin_Simulator/docs/step1_gui_skeleton.md
Mohamed Salem b808770573 Step 1: GUI skeleton for LIN Simulator (Python + C++)
- PyQt6 main window with Tx/Rx tables, connection dock, LDF toolbar,
  control bar with global send rate, and status bar
- C++ Qt6 equivalent with identical layout and feature parity
- About dialog: TeqanyLogix LTD / Developer: Mohamed Salem
- Application logo (SVG + PNG) with LIN bus waveform design
- Full test suites: Python (32 tests), C++ QTest (34 tests)
- Project plan and Step 1 documentation

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 16:40:52 +02:00

90 lines
3.5 KiB
Markdown

# Step 1 — GUI Skeleton
## What Was Built
The main window layout for the LIN Master Simulator using PyQt6 (Python).
## Architecture
```
MainWindow (QMainWindow)
├── Menu Bar
│ ├── File → Load LDF... (Ctrl+O), Exit (Ctrl+Q)
│ └── View → Toggle Connection panel
├── LDF Toolbar (top, fixed)
│ ├── LDF File path (read-only QLineEdit)
│ ├── Browse button → opens file dialog
│ └── Auto-reload checkbox (default: on)
├── Central Widget
│ └── QSplitter (vertical, resizable)
│ ├── Tx Panel (QGroupBox)
│ │ └── QTableWidget: Frame Name | Frame ID | Length | Interval (ms) | Data | Signals | Action
│ └── Rx Panel (QGroupBox)
│ └── QTableWidget: Timestamp | Frame Name | Frame ID | Data | Signals
├── Connection Dock (QDockWidget, left side, detachable)
│ ├── Device dropdown + Refresh button
│ ├── Baud Rate label (read-only, auto-detected from LDF's LIN_speed field)
│ ├── Connect / Disconnect buttons
│ ├── Status label (red "Disconnected")
│ └── Device info label
├── Control Bar (bottom toolbar, fixed)
│ ├── Schedule table dropdown
│ ├── Global Rate (ms) spinbox (1-10000ms, default 50ms)
│ ├── Start / Stop / Pause buttons (disabled)
│ └── Send Selected Frame button (disabled)
└── Status Bar
├── Temporary messages (left)
└── Connection indicator (right, permanent)
```
## Send Rate Hierarchy
When the scheduler runs, each frame's send interval is determined by priority:
1. **Per-frame interval** (Tx table "Interval (ms)" column) — highest priority, user override
2. **Global send rate** (Control bar spinbox) — default fallback for frames with no per-frame interval
3. **LDF schedule table** — auto-fills per-frame intervals when LDF is loaded
## Key Concepts Introduced
### PyQt6 Widget Tree
Every visible element is a QWidget. Widgets contain other widgets via layouts.
The root widget is QMainWindow which provides menu, toolbars, dock areas, and status bar for free.
### Layouts
- **QVBoxLayout**: stacks widgets vertically
- **QHBoxLayout**: stacks widgets horizontally
- **QSplitter**: like a layout but with a draggable divider
### Signals & Slots
Qt's event system. A signal (e.g., `button.clicked`) connects to a slot (any Python function).
Example: `self.btn_browse_ldf.clicked.connect(self._on_load_ldf)`
### QDockWidget
A panel that can be dragged to any window edge, floated, or hidden.
Used for the Connection panel so users can maximize table space during monitoring.
### Initial Widget States
Controls that require prerequisites (LDF loaded, device connected) start **disabled**.
This prevents users from triggering actions that would fail. We enable them as preconditions are met.
## Files
| File | Purpose |
|------|---------|
| `python/src/main.py` | Application entry point — creates QApplication, shows MainWindow |
| `python/src/main_window.py` | MainWindow class — all panel creation and layout |
| `python/tests/test_main_window.py` | 26 tests verifying widget tree structure and initial states |
## Running
```bash
# Launch the GUI
cd python/src && python main.py
# Run tests
cd python && python -m pytest tests/test_main_window.py -v
```
## Test Results
- 32 tests, all passing
- Tests cover: window properties, menu bar, toolbar, Tx/Rx tables (incl. Interval column), connection dock (incl. baud rate label), control bar (incl. global rate), status bar