PyHML Language Reference
PyHML (PyHMI Markup Language) is a declarative UI description format inspired by Qt QML. It uses a YAML-compatible, indented syntax to describe UI hierarchies. PyHML files are parsed at runtime, constructing a widget tree that the engine renders on the active display backend.
Basic Syntax
PyHML uses indentation to define parent-child relationships. Each line declares a widget or component, followed by its properties:
Window:
width: 320
height: 240
title: "My App"
Label:
text: "Hello, World!"
color: "#333333"
fontSize: 16
The Window is the root element. Label is a child of Window, indicated by indentation. Properties are assigned with key: value syntax.
Component Hierarchy
Nesting is defined by indentation. Each level of indentation creates a parent-child relationship:
Window:
layout: Column
padding: 10
Label:
text: "Username"
TextField:
id: username
CheckBox:
text: "Remember me"
Button:
text: "Login"
onClicked: login()
In this example, Label, TextField, CheckBox, and Button are all children of Window. The Column layout arranges them vertically.
Property Assignment
Properties are assigned using YAML-style syntax. Supported types:
| Type | Syntax | Example |
|---|---|---|
| String | Quoted or unquoted | text: "Hello" |
| Integer | Plain number | width: 320 |
| Float | Decimal number | opacity: 0.5 |
| Boolean | true / false | visible: true |
| Color | Hex string | color: "#FF5733" |
| List | Inline or block | values: [1, 2, 3] |
| Object | Nested mapping | font: {name: "Arial", size: 14} |
IDs and References
Widgets can be assigned an id for cross-component referencing:
Slider:
id: volume
min: 0
max: 100
value: 50
Label:
text: "Volume: {{ volume.value }}"
The id creates a reference that can be used in data bindings, signal handlers, and Python code.
Data Binding
PyHML supports one-way and two-way data binding using {{ }} expression syntax:
Label:
text: "{{ temperature.value }} °C"
TextField:
text: "{{= user.name }}"
Label:
text: "{{ battery.percent > 20 ? 'OK' : 'Low' }}"
One-way binding ({{ }}) updates the target when the source changes. Two-way binding ({{= }}) syncs changes in both directions.
Signal Handlers
Signal handlers use the on<SignalName> prefix. They accept Python expressions or function calls:
Button:
text: "Submit"
onClicked: submit_form()
Slider:
id: brightness
onValueChanged: set_light(value)
TextField:
id: search
onTextChanged: filter_results(text)
Available signals depend on the widget. Common signals: Clicked, ValueChanged, TextChanged, Pressed, Released, FocusIn, FocusOut.
Layouts
PyHMI supports two layout engines:
Flex Layout
Row and column layouts with alignment, spacing, and stretch factors.
Window:
layout: Column
spacing: 10
alignment: center
Label:
text: "Title"
Button:
text: "OK"
stretch: 1
Button:
text: "Cancel"
stretch: 1
Grid Layout
Row and column grid with span, alignment, and flexible sizing.
Window:
layout: Grid
columns: 2
rows: 2
spacing: 5
Label:
text: "Name"
TextField:
id: name
Label:
text: "Age"
TextField:
id: age
columnSpan: 2
Animations
Animations are declared inline on widgets:
Button:
text: "Click me"
animations:
- property: opacity
from: 1.0
to: 0.5
duration: 300
easing: easeInOut
trigger: pressed
Supported easing curves: linear, easeIn, easeOut, easeInOut, bounce.
Style Templates
Style templates define reusable visual properties. Applied at widget, class, or theme level:
styles:
primaryButton:
backgroundColor: "#4A90D9"
textColor: "#FFFFFF"
borderRadius: 8
padding: 10
fontSize: 14
Window:
Button:
text: "Submit"
style: primaryButton
Custom Elements
Custom widgets defined in Python can be used in PyHML:
Window:
MyGauge:
value: 75
maxValue: 100
color: "#4A90D9"
onValueChanged: update_label(value)
Custom elements support property binding, event handling, and style templates. They can be nested within other custom elements.
QML Import
PyHMI supports loading Qt QML files directly. The QML importer translates QML syntax to PyHMI widget trees:
from pyhmi import Application
app = Application(backend="sdl2")
app.load_qml("design.qml")
app.run()
Supported QML features: property assignment, signal handlers, data binding, layouts, and animations.
Scene Management
Scenes are self-contained PyHML files. Navigation is handled by the scene manager:
from pyhmi import Application
app = Application(backend="sdl2")
app.load_scene("login.pyhml")
# In Python code:
app.navigate("dashboard.pyhml", data={"user": username})
app.back()
Scenes support data segue for passing data between scenes during navigation.