Qt Pie¶
Tasty way to build Qt apps
Declarative. Reactive. Delightful.
from qtpie import entrypoint, make, state, widget
from qtpy.QtWidgets import QLabel, QPushButton, QWidget
@entrypoint
@widget
class Counter(QWidget):
# Tracked state - changes update the UI
count: int = state(0)
# Updates automatically when count changes
label: QLabel = make(QLabel, bind="Count: {count}")
# Calls increment() when clicked
button: QPushButton = make(QPushButton, "+1", clicked="increment")
def increment(self) -> None:
self.count += 1
| Light mode | Dark mode |
|---|---|
![]() |
![]() |
Click the button. State changes. Label updates. That's it.
What's in the box¶
state()– reactive variables that update the UIbind="{x}"– format expressions with auto-refreshclicked="method"– signal connections by name@widget– dataclass-style components with automatic layoutsWidget[T]– type-safe model binding- SCSS hot reload – style with CSS classes
- Async support –
async defjust works - pyright strict – full type safety, no compromises
Reactive State¶
Change a variable. Widgets update.
count: int = state(0)
label: QLabel = make(QLabel, bind="Count: {count}")
self.count += 1 # Label updates instantly
Format Expressions¶
Template syntax in bindings:
Automatic Layouts¶
Widgets are fields. Order is layout.
@widget
class MyWidget(QWidget):
top: QLabel = make(QLabel, "Top")
middle: QLabel = make(QLabel, "Middle")
bottom: QLabel = make(QLabel, "Bottom")
@widget(layout="form")
class MyForm(QWidget):
name: QLineEdit = make(QLineEdit, form_label="Name:")
email: QLineEdit = make(QLineEdit, form_label="Email:")
Model Binding¶
Fields match model properties. Binding is automatic.
@dataclass
class Person:
name: str = ""
age: int = 0
@widget
class PersonEditor(QWidget, Widget[Person]):
name: QLineEdit = make(QLineEdit) # binds to model.name
age: QSpinBox = make(QSpinBox) # binds to model.age
Full Qt Access¶
QtPie is a layer, not a cage. All of Qt is still there.
@widget
class MyWidget(QWidget):
label: QLabel = make(QLabel, "Hello")
def setup(self) -> None:
# Standard Qt, whenever you need it
self.setWindowTitle("My App")
self.label.setStyleSheet("color: red;")

