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

3.5 KiB

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

# 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