Core API
This section documents the core reactivity primitives and the application entry point.
pymiro
pymiro: Signal-native, declarative GUI framework for Python.
App
The main application entry point for pymiro.
This class sets up the Qt application, event loop, and theme, and mounts your root component into the main window.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
title
|
str
|
The window title. |
'pymiro'
|
width
|
int
|
The initial window width. |
800
|
height
|
int
|
The initial window height. |
600
|
dev
|
bool
|
If True, enables hot-reloading and development logging. |
False
|
theme
|
str | Theme
|
The theme to use ("default", "dark", or a custom Theme object). |
'default'
|
Example
from pymiro import App, component
from pymiro.components import Text
@component
def HelloWorld():
return Text("Hello, world!")
if __name__ == "__main__":
app = App(title="My App", width=400, height=300)
app.run(HelloWorld)
Source code in pymiro/app.py
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 | |
Computed
Bases: Protocol[T_co]
Protocol for a derived reactive value.
Source code in pymiro/core/signals.py
58 59 60 61 | |
Signal
Bases: Protocol[T]
Protocol for a reactive signal.
Source code in pymiro/core/signals.py
50 51 52 53 54 55 | |
batch
batch(fn: Callable[[], T]) -> T
batch() -> contextlib.AbstractContextManager[None]
batch(fn: Callable[[], T] | None = None) -> Any
Batch multiple signal updates into a single execution frame.
When you update multiple signals inside a batch, effects depending on those signals will only run once after the batch completes, preventing unnecessary intermediate renders.
Can be used as a context manager with batch(): or as a higher-order
function batch(fn).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
fn
|
Callable[[], T] | None
|
Optional function to run inside the batch. |
None
|
Example
first = signal("John")
last = signal("Doe")
effect(lambda: print(f"Name: {first()} {last()}"))
with batch():
first.set("Jane")
last.set("Smith")
# Effect only prints "Name: Jane Smith" once
Source code in pymiro/core/signals.py
349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 | |
component
component(fn: F) -> F
Wrap a function into a pymiro component.
Components are the building blocks of a pymiro UI. They are regular Python
functions that return a VNode (like Text, Button, or VStack) and
are wrapped in the @component decorator. This decorator enables the use
of hooks (like use_signal or use_effect) within the function.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
fn
|
F
|
The function returning a VNode. |
required |
Returns:
| Type | Description |
|---|---|
F
|
The wrapped component function. |
Example
from pymiro import component
from pymiro.components import Button, Text, VStack
from pymiro.core.hooks import use_signal
@component
def Counter():
count, set_count = use_signal(0)
return VStack(
Text(lambda: f"Count: {count()}"),
Button("Increment", on_click=lambda: set_count(count() + 1))
)
Source code in pymiro/core/component.py
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 | |
computed
computed(fn: Callable[[], T]) -> Computed[T]
Create a reactive computed value derived from other signals.
A computed value automatically tracks which signals it reads. When those signals change, the computed value marks itself as dirty and lazily re-evaluates only when its value is read again.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
fn
|
Callable[[], T]
|
A function that computes a value based on signals. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
Computed |
Computed[T]
|
A computed object. Call it to read the derived value. |
Example
first = signal("Hello")
last = signal("World")
full_name = computed(lambda: f"{first()} {last()}")
print(full_name()) # "Hello World"
first.set("Hi")
print(full_name()) # "Hi World"
Source code in pymiro/core/signals.py
281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 | |
effect
effect(fn: Callable[[], None]) -> Callable[[], None]
Create a side effect that automatically re-runs when dependencies change.
The function is run immediately to determine its dependencies. Whenever any of the signals read during execution change, the function runs again.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
fn
|
Callable[[], None]
|
A function containing side effects (e.g., printing, DOM updates). |
required |
Returns:
| Name | Type | Description |
|---|---|---|
Callable |
Callable[[], None]
|
A disposer function. Call it to stop the effect and clean up its subscriptions. |
Example
count = signal(0)
# Runs immediately and prints "Count is 0"
dispose = effect(lambda: print(f"Count is {count()}"))
count.set(1) # Automatically prints "Count is 1"
dispose() # Stop listening
count.set(2) # Nothing prints
Source code in pymiro/core/signals.py
310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 | |
signal
signal(value: T) -> Signal[T]
Create a reactive signal holding a value.
A signal is the core reactive primitive. It holds a value and notifies subscribers (like effects or computed values) whenever the value changes.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
value
|
T
|
The initial value of the signal. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
Signal |
Signal[T]
|
A signal object. Call it |
Example
count = signal(0)
print(count()) # 0
count.set(1)
print(count()) # 1
Source code in pymiro/core/signals.py
255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 | |