Qt Kiosk Home Page and Navigation Architecture¶
Overview¶
The Qt kiosk interface of the Wine Cellar system is composed of two cooperating components:
- HomePage (
home.py) - Application Shell (
app_shell.py)
Together they implement the manual operations interface used on the Raspberry Pi touchscreen inside the cellar.
Responsibilities are divided as follows:
| Component | Responsibility |
|---|---|
| HomePage | Tile-based touch menu |
| AppShell | Global navigation bar, page routing, keyboard overlay |
Files:
apps/winecellar/frontend/qt_kiosk/pages/home.py
apps/winecellar/frontend/qt_kiosk/app_shell.py
The ROI calibration feature belongs to the navigation bar of the application shell, not the HomePage tiles.
Architecture¶
flowchart TD
APP["AppShell (Qt Application Shell)"]
HEADER["Top Navigation Bar"]
STACK["Page Stack"]
HOME["HomePage"]
BINS["BinsPage"]
INV["InventoryPage"]
MAT["MaterialsPage"]
MOV["MovementsPage"]
SHELF["ShelfPage"]
ROI["PinceRoiPage"]
APP --> HEADER
APP --> STACK
STACK --> HOME
STACK --> BINS
STACK --> INV
STACK --> MAT
STACK --> MOV
STACK --> SHELF
STACK --> ROI
The shell controls which page is visible using a QStackedWidget.
HomePage¶
Purpose¶
HomePage is the touch-oriented tile menu displayed when the kiosk starts.
Its purpose is to provide fast access to common operational workflows.
It does not contain all pages of the application.
Maintenance pages (such as ROI calibration) are accessed through the header navigation.
Layout Structure¶
flowchart TD
ROOT["Vertical Layout"]
HEADER["Title"]
SCALE["UI Scale Selector"]
GRID["Tile Menu"]
SPACER["Stretch"]
ROOT --> HEADER
ROOT --> SCALE
ROOT --> GRID
ROOT --> SPACER
Header Section¶
Displays:
Wine Cellar
Touch menu • LAN-only • Raspberry Pi
This communicates the context of the application.
UI Scale Selector¶
The kiosk runs on a 7-inch Raspberry Pi touchscreen, therefore UI scaling must be adjustable.
Scale values:
0.6
0.7
0.8
0.9
1.0
1.1
1.2
Displayed as:
60% – 120%
The scale is stored via:
set_ui_scale()
The page detects the closest stored scale using:
_nearest_scale_index()
Changes require restarting the UI to fully apply.
Tile Menu¶
The tile grid uses two columns.
| Row | Left | Right |
|---|---|---|
| 1 | Goods Movements | Material Master |
| 2 | Inventory Take – by Wine | Inventory Take – by Storage Bin |
| 3 | Shelf | Exit |
Each tile is implemented with a BigButton widget optimized for touch.
Tile Navigation¶
Navigation is performed using the callback:
self.nav_to(page_name)
This delegates navigation to the application shell.
Tiles¶
Goods Movements¶
Goods Movements
GI / GR / INV
Primary workflow for:
- Goods Issue
- Goods Receipt
- Inventory adjustments
Material Master¶
Material Master
Manage and browse wines
Allows browsing and editing wine records.
Inventory Take – by Wine¶
Inventory Take – by Wine
Manage Inventory by Wine
Inventory operations organized by wine.
Inventory Take – by Storage Bin¶
Inventory Take – by Storage Bin
Manage Inventory by Bin
Inventory operations organized by physical storage bin.
Shelf¶
Shelf
Tap bins to open Movements
Displays a graphical map of the cellar shelf.
From this page the user can:
- inspect bin contents
- start inventory adjustments directly
Exit¶
Exit
Close kiosk UI and reveal desktop
Closes the Qt interface while backend services remain active.
Application Shell¶
The AppShell is the main Qt container of the kiosk application. :contentReference[oaicite:1]{index=1}
Responsibilities include:
- global navigation bar
- page stack management
- status bar
- virtual keyboard overlay
- geometry enforcement for the touchscreen
- background worker tasks
Navigation Bar¶
The header navigation bar provides direct access to all pages.
Buttons:
| Button | Target Page |
|---|---|
| Home | HomePage |
| Bins | BinsPage |
| Inventory | InventoryPage |
| Materials | MaterialsPage |
| Shelf | ShelfPage |
| Movements | MovementsPage |
| Keyboard | Virtual keyboard toggle |
| ROI | PinceRoiPage |
| Quit | Exit kiosk UI |
ROI Calibration Page¶
The ROI button opens the PinceRoiPage.
Navigation:
self.btnROI.clicked.connect(lambda: self.navigate("pince_roi"))
Purpose of this page:
- calibrate shelf ROI polygons
- maintain bin boundaries used by the vision system
The page interacts with the vision calibration workflow which includes:
generate_mask_for_polc.py
ROI_ADjustment_from_PNG.py
These tools define the cell polygons used for cropping shelf images.
Because ROI calibration modifies the geometry used by the automated vision pipeline, it is placed in the header navigation rather than the main menu.
This reduces the risk of accidental changes during daily operations.
Page Stack¶
The application uses a QStackedWidget to manage page navigation.
Pages registered in the shell:
home
bins
inventory
materials
movements
pince_roi
shelf
Navigation replaces the currently visible page in the stack.
Navigation Logic¶
Unified navigation entry point:
navigate(name, **payload)
Steps:
- locate requested page
- activate page in stack
- call optional hooks
- update status bar
Hooks supported:
page.on_show()
page.on_navigate(payload)
Status Bar¶
The bottom status bar displays system messages.
Typical messages:
Opened: bins
Opened: movements
UI scale saved
cleanup done
The bar remains permanently visible and cannot shrink to zero height.
Virtual Keyboard¶
The kiosk includes an on-screen keyboard overlay.
Features:
- floating overlay
- not part of layout
- toggled from header button
Keyboard is hosted by:
VirtualKeyboard
Screen Geometry Enforcement¶
The shell ensures the UI never exceeds the physical screen.
Method:
_enforce_screen_geometry()
This:
- clamps window size
- prevents dialogs from resizing the UI
- keeps keyboard alignment stable
Movements Prefill¶
The shell provides helper methods to open the Movements page with prefilled parameters.
Examples:
open_movements_prefill()
open_movements_prefill_GI()
These methods pass payload values through the navigation system.
Background Worker Example¶
The shell can run background tasks using Worker.
Example:
start_label_cleanup()
This performs orphan label cleanup asynchronously and reports status in the UI.
Failure Modes¶
Possible issues include:
| Issue | Cause |
|---|---|
| page not found | incorrect navigation name |
| import failure | missing dependencies |
| keyboard overlay issues | geometry mismatch |
| background worker errors | API failures |
These errors are surfaced via the status bar.
Summary¶
The kiosk interface is composed of two layers:
| Layer | Responsibility |
|---|---|
| HomePage | touch-friendly operational menu |
| AppShell | global navigation and application control |
ROI calibration is intentionally placed in the header navigation bar instead of the home tiles, ensuring that vision calibration tools remain accessible but protected from accidental use during normal cellar operations.