PyHMI

Open-source, royalty-free Python graphics library for building graphical user interfaces on embedded systems and desktop Linux.

Python 3 Apache 2.0 3 Runtimes 70+ Widgets

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:

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