"PUI" Python Declarative UI Framework
Project description
What is PUI
PUI is a declarative UI framework with two-way data binding
Installation
pip install QPUIQ
Get Started
Hello World
# example/hello_world.py
from PUI.PySide6 import *
class Example(Application):
def content(self):
with Window(title="test", size=(320,240)):
Label("Hello world")
root = Example()
root.run()
State & Data Binding
# example/pyside6_textfield.py
from PUI.PySide6 import *
data = State()
data.var = 0
class QtExample(QtApplication):
def content(self):
with QtWindow(title="blah"):
with QtVBox():
with QtHBox():
QtButton("-", self.on_minus)
QtLabel(f"{data.var}")
QtButton("+", self.on_plus)
QtLineEdit(data("var")) # binding
def on_minus(self):
data.var -= 1
def on_plus(self):
data.var += 1
root = QtExample()
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/pyside6_canvas.py
from PUI.PySide6 import *
data = State()
data.var = 50
class QtExample(QtApplication):
def content(self):
with QtWindow(title="blah", size=(640,480)):
with QtVBox():
with QtCanvas():
QtCanvasText(data.var, data.var/2, f"blah {data.var}")
QtCanvasLine(data.var, data.var, data.var*2, data.var*3)
with QtHBox():
QtButton("-", self.on_minus)
QtLabel(f"{data.var}")
QtButton("+", self.on_plus)
def on_minus(self):
data.var -= 1
def on_plus(self):
data.var += 1
from PySide6 import QtWidgets
root = QtExample()
root.run()
Cookbook
python -m cookbook
(requires pygments for syntax highlight)
Backends
Tier-1
- PySide6
Lower Priority
- tkinter
- PyQt5
- flet
- no canvas before v0.6.0
- urwid (Text Mode)
- no canvas
Generic Expression
- Take a look at PUI/PySide6/__init__.py
Elements
- HBox()
- VBox()
- Spacer()
- Button(text, callback, *cb_args, **cb_kwargs)
- Label(text)
- .click(callback, *cb_args, **cb_kwargs)
- TextField(binding)
- ProgressBar(progress
0-1
) - Scroll()
- Canvas
- CanvasText
- CanvasLine(x1, y1, x2, y2, color=0xFF0000, width=2)
Layout
- .layout(width=320, height=240, weight=1)
Hot Reload
Add these lines to your view file and run with reloadium
import reloadium
# reloadium: after_reload
def after_reload(actions):
PUIView.reload()
TODO
Use threading.locals() instead of inspect- State
Update TriggerBindingStateListStateDict- Lazy UI?
- StateObject decorator
- Adapters
Split Application/Window, multi-windows- UI Flow
- Navigation Stack
- View Router
- Model Window/Dialog
LabelButtonTextFieldTimelimeView- Layout
HBoxVBox- ZBox
- Grid
- Row
- Column
- SwiftUI style overlay ??
- Canvas
TextLine- Rect
- Arc
- Image
- ...
- Table
- Tree
Scrollbar (or as a layout setting)
- Better DOM syncer
- Prevent unnecessary nested update
- Trace Event Source (TextField) and prevent update it DOM Sync
- Pydantic State
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
QPUIQ-0.1.13.tar.gz
(20.6 kB
view details)
Built Distribution
QPUIQ-0.1.13-py3-none-any.whl
(33.8 kB
view details)
File details
Details for the file QPUIQ-0.1.13.tar.gz
.
File metadata
- Download URL: QPUIQ-0.1.13.tar.gz
- Upload date:
- Size: 20.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.2 CPython/3.11.3
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | f8b97f16c10ac3be81e4ee12a16e6cdbca94d09130220fd7fd7a942fceb8396c |
|
MD5 | 7ed22be25df13e00af4f6a97d13fe52d |
|
BLAKE2b-256 | c3ef0937d3648a5a24c7303602ad3f4b1ee0e009201e6e0de95ffea11b28406f |
File details
Details for the file QPUIQ-0.1.13-py3-none-any.whl
.
File metadata
- Download URL: QPUIQ-0.1.13-py3-none-any.whl
- Upload date:
- Size: 33.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.2 CPython/3.11.3
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | adef6354b1f31ed1397359dd725dd434fc5b75399cfaedb62d4757aa566f82a9 |
|
MD5 | 1f0dc7d8732db23bb7bfa193ddce0ba4 |
|
BLAKE2b-256 | 3c6a6b8f3d9f4574db8c9a06028693f285cdfbf225e8f0527eb0293affe116e4 |