PyHMI
Open-source, royalty-free Python graphics library for building graphical user interfaces on embedded systems and desktop Linux.
One Library, Three Runtimes
PyHMI bridges the gap between minimal embedded GUIs and full-featured frameworks. The same UI description runs across all platforms:
Desktop Linux
Direct rendering to /dev/fb0 framebuffer. No X11 or Wayland dependency. Runs on Raspberry Pi, BeagleBone, and any Linux SBC.
- Native framebuffer via mmap
- RGB565, RGB888, grayscale
- evdev touch input
- <5 MB RAM
Microcontrollers
Runs on CircuitPython 9+, rendering to SPI LCD displays. Supports ST7735, ST7789, ILI9341, and HX8357 controllers.
- CircuitPython displayio
- Partial updates for efficiency
- USB HID input via tinyusb
- <500 KB RAM
Emulation
Cross-platform SDL2 window for design and testing. Runs on macOS, Linux, and Windows — no embedded hardware required.
- SDL2 rendering backend
- Keyboard and mouse input
- Identical PyHML files
- 60 FPS target
Declarative UI with PyHML
PyHMI uses PyHML (PyHMI Markup Language) — a YAML-compatible, QML-inspired syntax for describing UIs declaratively:
Window:
width: 320
height: 240
title: "Dashboard"
layout: Column
Label:
text: "Temperature"
fontSize: 24
Slider:
id: tempSlider
min: 0
max: 100
value: 22
onValueChanged: print("Temp:", value)
Label:
text: "{{ tempSlider.value }} °C"
PyHML supports component hierarchy, property binding, signal handlers, data binding, and layout declarations. PyHMI also supports QML import for loading existing Qt QML designs.
Comprehensive Widget Catalog
PyHMI ships with 70+ widgets, covering all elements from uGUI, LVGL, TouchGFX, emWin, and Qt/Quick. Browse the interactive gallery:
Basic
Label, Button, CheckBox, RadioButton, Switch, Slider, ProgressBar, Dial, TextField, Image, LED, DropDown
Input
VirtualKeyboard, TextArea, ComboBox, Spinbox, ButtonMatrix, SearchField, Roller, Tumbler
Container
Container, Frame, GroupBox, ScrollView, Window, Page, SplitView, Drawer
Chart / Graph
LineChart, AreaChart, BarChart, Gauge, Arc, Meter, Scale, LED
Media
Canvas, Video, GIF, AnimationImage
Navigation
TabBar, TabView, Menu, MenuBar, StackView, SwipeView, TileView, PageIndicator
Key Features
Layout Engine
Flex (row/column) and Grid layouts with alignment, spacing, stretch, and span. Responsive across resolutions.
Data Binding
One-way and two-way binding between widget properties and data models. Observable properties with dependency tracking.
Animations
Property animations with easing curves, keyframes, and timeline support. Declarative in PyHML.
Style Templates
Reusable style definitions at widget, class, or theme level. Cascade properties for consistent theming.
Scene Management
Load, unload, and navigate between scenes. Dynamic loading from Python code. Data segue between scenes.
Custom Elements
Define custom widgets via class inheritance. Nestable in PyHML and other custom elements. Full Python control.
Market Position
PyHMI fills the gap between minimal embedded GUIs and full-featured desktop frameworks:
| Feature | uGUI | LVGL | TouchGFX | Qt/Quick | PyHMI |
|---|---|---|---|---|---|
| Language | C | C | C++ | C++ / QML | Python |
| Declarative UI | No | XML (Pro) | Designer | QML | PyHML + QML |
| Linux framebuffer | No | Yes | No | Yes | Yes |
| SPI LCD / MCU | No | Yes | No | No | Yes |
| Memory (desktop) | ~10 KB | ~32 KB | ~1-2 MB | ~100+ MB | ~2 MB |
| Widgets | 6 | 38+ | 24+ | 50+ | 70+ |
| License | MIT | MIT | Commercial | LGPL v3 | Apache 2.0 |
| Emulation | No | Simulator | Designer | Native | SDL2 |
Quick Start
1. Install
git clone https://github.com/schreinerman/pyhmi
cd pyhmi
bash install.sh
source .venv/bin/activate
2. Minimal Example
from pyhmi import (
Engine, Sdl2Display,
Label, Window, FlexLayout
)
display = Sdl2Display(
width=320, height=240,
title="Hello PyHMI"
)
engine = Engine(display)
window = Window()
window.width = 320
window.height = 240
window.background_color = (30, 30, 30, 255)
label = Label()
label.text = "Hello, PyHMI!"
label.font_size = 20
label.text_color = (255, 255, 255)
window.add_child(label)
engine.set_root(window)
engine.run()
3. PyHML File
from pyhmi import (
Engine, Sdl2Display,
PyHMLParser, FlexLayout
)
display = Sdl2Display(
width=320, height=240
)
engine = Engine(display)
parser = PyHMLParser(engine)
root = parser.parse_file(
"dashboard.pyhml"
)
engine.set_root(root)
engine.run()
4. Project Generator
# Quick start (2 questions)
python -m pyhmi.cli.generator \
--simple myproject
# Full wizard (8 questions)
python -m pyhmi.cli.generator \
--advanced myproject