Skip to main content

"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()

Hello World

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()

State & Data Binding

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)

....

View Component

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
...

Layout & Styling

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()

Canvas

Cookbook

python -m cookbook PySide6 (requires pygments for syntax highlight)

Cookbook 1 Cookbook 2

python -m cookbook textual Cookbook textual

python -m cookbook flet Cookbook flet

python -m cookbook tkinter Cookbook tkinter

Hot-Reload with Reloadium

Hot-Reload with Reloadium

Backends

Tier-1

  • PySide6

Lower Priority

Components

Generic PySide6 flet tkinter textual
Application QApplication Page Tk App
Window QMainWindow ✓(Single) Toplevel ✓(Single)
HBox QHBoxLayout Row Frame(grid) Horizontal
VBox QVBoxLayout Column Frame(grid) Vertical
Spacer QSpacerItem
Label QLabel Text Label Label/Button
Button QPushButton ElevatedButton Button Button
Checkbox QCheckBox Checkbox Checkbutton Checkbox
RadioButton QRadioButton Radio Radiobutton RadioButton
Canvas ✓(QWidget) Canvas Canvas -
TextField QLineEdit TextField Entry Input
ProgressBar QProgressBar ProgressBar Progressbar ProgressBar
Scroll QScrollArea ScrollableContainer
Text QLabel Text Label Text
Html QLabel ⚠ Text ⚠ Label ⚠ Text
MarkDown QLabel Markdown ⚠ Label ⚠ Text
Combobox QComboBox - - -
ComboboxItem - - -
Tabs QTabWidget Tabs Notebook Tabs
Tab Tab
MenuBar QMenuBar - - -
Menu QMenu - - -
MenuAction QAction - - -
MdiArea QMdiArea - - -
MdiSubWindow QMdiSubWindow - - -
Splitter QSplitter - - -
(Wrapper) QtWrapper - - -

Interfaces

  • Button(text)
    • .click(callback, *cb_args, **cb_kwargs)
  • Label(text)
    • .click(callback, *cb_args, **cb_kwargs)
  • TextField(binding)
  • ProgressBar(progress 0-1)
  • Checkbox(label, model)
  • RadioButton(label, value, model)
  • Canvas
    • .drawText(x, y, text)
    • .drawLine(x1, y1, x2, y2, color=0xFF0000, width=2)
    • .drawPolyline([x1, y2, ..., xn, yn], color=0xFF0000, width=2)

Modifiers

  • .layout(width=320, height=240, weight=1, padding=, margin=)
  • .style(color=0xFF0000, bgColor=0x0, fontSize=16, fontWeight="bold", fontFamily="Arial")
  • .qt(HorizontalPolicy=, VerticalPolicy=, SizeConstraint=, StyleSheet={})
  • .flet(k=v)

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

  • Tabs(tabposition)
  • Lazy List
  • StateObject decorator
  • UI Flow
    • Navigation Stack
    • View Router
    • Model Window/Dialog
  • Layout
    • ZBox
    • Grid
      • Row
      • Column
    • SwiftUI style overlay ??
  • Canvas
    • Rect
    • Arc
    • Image
    • ...
  • Table
  • Tree
  • Dialog
  • State with Pydantic support?

Project details


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.2.4.tar.gz (27.3 kB view details)

Uploaded Source

Built Distribution

QPUIQ-0.2.4-py3-none-any.whl (45.0 kB view details)

Uploaded Python 3

File details

Details for the file QPUIQ-0.2.4.tar.gz.

File metadata

  • Download URL: QPUIQ-0.2.4.tar.gz
  • Upload date:
  • Size: 27.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.11.3

File hashes

Hashes for QPUIQ-0.2.4.tar.gz
Algorithm Hash digest
SHA256 1f0b18cd44e5331e06cea7b25a67491b49288b4ca463f373509569f3fde22cb3
MD5 e2b5d89a3046e08d5ad83109097542b3
BLAKE2b-256 766b7c74799124ceed5da51c64eaba7c190e2052395440f6b82c3cad2980de36

See more details on using hashes here.

File details

Details for the file QPUIQ-0.2.4-py3-none-any.whl.

File metadata

  • Download URL: QPUIQ-0.2.4-py3-none-any.whl
  • Upload date:
  • Size: 45.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.11.3

File hashes

Hashes for QPUIQ-0.2.4-py3-none-any.whl
Algorithm Hash digest
SHA256 851d3a1aa7c92eb085ced8b1dd8ddb81abb4f8f4647bcb0d3ac5825d71009e76
MD5 d3ae9d0cec91f42498151f08327e047f
BLAKE2b-256 6e19acc3de7d6487b60b2bb3f9465fa33c6359418cd8030ee43bc29360864b32

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page