"PUI" Python Declarative UI Framework
Project description
What is PUI
PUI is a reactive/declarative UI framework with two-way data binding. PUI doesn't do UI itself, it turns imperative UI libraries into reactive/declarative flavor with virtual DOM and aims to maintain interoperability.
CPPUI: Experimental C++ Version
Installation
pip install QPUIQ
# Optional, for hot-reload
pip install jurigged
# Optional, for PySide6 backend
pip install PySide6
# Optional, for textual backend
pip install textual
# Optional, for wxPython backend
pip install wxPython
# Optional, for flet backend
pip install flet
Get Started
Hello World
# example/hello_world.py
from PUI.PySide6 import *
@PUIApp
def Example():
with Window(title="test", size=(320,240)):
Label("Hello world")
root = Example()
root.run()
State & Data Binding
# example/generic_textfield.py
from PUI.PySide6 import *
data = State()
class Example(Application):
def __init__(self):
super().__init__()
data.var = 0
def content(self):
with Window(title="blah"):
with VBox():
with HBox():
Button("-").click(self.on_minus)
Label(f"{data.var}")
Button("+").click(self.on_plus)
TextField(data("var")) # binding
def on_minus(self):
data.var -= 1
def on_plus(self):
data.var += 1
root = Example()
root.run()
View Component
# example/bleak_list.py
....
@PUI # View Component
def DeviceView(device, advertising_data):
Label(f"{device.address} {device.name} {advertising_data.rssi}")
class GUI(Application):
def __init__(self, state):
super().__init__()
self.state = state
def content(self):
with Window(title="BLE List"):
with VBox():
Label(f"Found {len(self.state.scanned_devices)} devices")
for device, advertising_data in self.state.scanned_devices:
DeviceView(device, advertising_data)
....
Layout & Styling
# example/pyside6_feedparser.py
...
with VBox():
Label(title).qt(StyleSheet={"font-weight":"bold"}) # QT-specific
with HBox():
with Scroll():
with VBox():
for i,e in enumerate(entries):
Label(e.title).click(self.entry_selected, i)
Spacer()
with Scroll().layout(weight=1): # Generic Layout Parameter
if 0 <= selected and selected < len(entries):
(Text(entries[selected].description)
.layout(padding=10) # Generic Layout Parameter
.qt(StyleSheet={"background-color":"white", "color":"black"})) # QT-specific
...
Canvas
# example/generic_canvas.py
from PUI.PySide6 import *
data = State()
class Example(Application):
def __init__(self):
super().__init__()
data.var = 50
def content(self):
with Window(title="blah", size=(640,480)):
with VBox():
Canvas(self.painter, data.var)
with HBox():
Button("-").click(self.on_minus)
Label(f"{data.var}").layout(weight=1)
Button("+").click(self.on_plus)
@staticmethod
def painter(canvas, var):
canvas.drawText(var, var/2, f"blah {var}")
canvas.drawLine(var, var, var*2, var*3, color=0xFFFF00)
def on_minus(self):
data.var -= 1
def on_plus(self):
data.var += 1
root = Example()
root.run()
Cookbook
python -m cookbook PySide6 (requires pygments for syntax highlight)
python -m cookbook textual
python -m cookbook flet
python -m cookbook tkinter
Hot Reload
pip install jurigged
Then PUI will take care of view update (code)
Backends
Tier-1
- PySide6
Lower Priority
- wx
- tkinter
- flet
- textual (Text Mode)
- no canvas
Documents
Used by
TODO
- Dump with layout parameters and add test cases
- Toga
- [ISSUE] flet layout sizing (cookbook scroll example)
- nested state trigger
- set state in PUIView init
- set state in setup() ?
- Tabs(
tabposition) - Lazy List
- UI Flow
- Navigation Stack
- View Router
- Model Window/Dialog
- Layout
- SwiftUI style overlay ??
- Canvas
- Arc
- ...
- State with Pydantic support?
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file qpuiq-0.31.tar.gz.
File metadata
- Download URL: qpuiq-0.31.tar.gz
- Upload date:
- Size: 49.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
60217c2d9732196a0f2c0282944a2b604eb1ec812ea11011e540f885425941c0
|
|
| MD5 |
5c0e5c67dda343910d639fa23a0f55d4
|
|
| BLAKE2b-256 |
cde1a1abac9715e5835c8bd845b3f119e6a1a94f357220a7f17277643ff23629
|
File details
Details for the file qpuiq-0.31-py3-none-any.whl.
File metadata
- Download URL: qpuiq-0.31-py3-none-any.whl
- Upload date:
- Size: 76.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1326d470e563c5c052346c8dc75d030717296764e1671d55ba1da775858b1af2
|
|
| MD5 |
e13d2a2b54316900f58579b9e5edd93c
|
|
| BLAKE2b-256 |
1274334711f5cb3b6741514b3b307de3553038e3c505bcbcaaf8eb6bd269ec11
|