Overview
TheMainWindow class is the top-level PyQt6 window for Klaus. It assembles the camera widget, chat feed, session panel, and status bar into a unified interface with a horizontal splitter layout.
Module: klaus.ui.main_window
Inherits: QMainWindow (PyQt6)
Class Definition
Signals
MainWindow emits PyQt6 signals for user actions:Emitted when the user selects a different session. Argument is
session_id.Emitted when the user creates a new session. Argument is the session
title.Emitted when the user renames a session. Arguments are
session_id and new_title.Emitted when the user deletes a session. Argument is
session_id.Emitted when the user replays an exchange. Argument is
exchange_id.Emitted when the user toggles between push-to-talk and voice-activated mode.
Emitted when the user stops the current operation.
Emitted when the user clicks the settings gear button.
Emitted when the push-to-talk key is pressed down.
Emitted when the push-to-talk key is released.
Emitted when the mode toggle key is pressed.
Constructor
- Header with app title, session title label, and settings button
- Horizontal splitter with camera/session panel on the left (300px) and chat widget on the right (700px)
- Status widget at the bottom
- Dark theme and title bar styling
Layout Structure
The window uses aQVBoxLayout with three main sections:
-
Header (
QWidgetwith#klaus-headerobject name)- Fixed height:
theme.HEADER_HEIGHT - Contains app title, session title label, and settings button
- Fixed height:
-
Body (
QSplitterhorizontal)- Left panel: Camera preview + session list
- Right panel: Chat widget
- Initial sizes:
[300, 700]
-
Status bar (
StatusWidget)- Shows current mode (Idle/Listening/Thinking/Speaking)
- Contains mode toggle and stop buttons
Widget Properties
Live camera preview widget in the left panel.
Session list sidebar with context menu for rename/delete.
Scrollable chat feed showing conversation history.
Status bar at the bottom with mode indicator and controls.
Methods
Session Management
id, title, and optionally updated_at and exchange_count.
Hotkey Configuration
"F2", "F3", "Space", etc. Resolves keys using resolve_qt_key() helper.
On macOS with identical PTT and toggle keys, the toggle hint is updated to show Shift+{key} for disambiguation.
Parameters:
ptt_key: Key name for push-to-talk (e.g."F2")toggle_key: Key name for mode toggle (e.g."F3")
Keyboard Event Handling
hotkey_action_for_keypress() to determine if the key should trigger PTT or toggle based on:
- Key value
- Shift modifier state
- Configured PTT and toggle keys
- Platform (macOS uses shifted variants for same-key PTT/toggle)
ptt_key_pressed or toggle_key_pressed signals accordingly.
ptt_key_released when the PTT key is released and was previously armed.
Helper Functions
resolve_qt_key
'F2') to a Qt.Key integer value. Supports:
- Function keys:
F1-F12 - Special keys:
Space,Escape,Tab,Backspace - Single characters: Converted to uppercase ASCII code
ValueError if the key name is unrecognized.
hotkey_action_for_keypress
"ptt_down", "toggle", or None based on key press analysis.
macOS special case: When PTT and toggle keys are the same on Darwin, unshifted triggers "ptt_down" and shifted triggers "toggle".
Shifted variants: Applies _QT_SHIFTED_VARIANTS mapping (e.g. ± → § on macOS ISO keyboards).
Usage Example
Notes
- Qt key events only fire when the window is focused; global hotkeys require
pynputbackend (seemain.py) - Dark title bar is applied via
theme.apply_dark_titlebar()on Windows - Auto-repeat key events are ignored to prevent duplicate signals
- Splitter allows user to resize left/right panels; left panel stretch factor is 0, right is 1