Decorator-driven GUI framework for Python — generate PySide6 UIs from type annotations
Project description
decoui
Decorator-driven GUI framework for Python. Annotate your methods — decoui generates a full PySide6 desktop app automatically.
Features
- Zero UI code — decorate a class and its methods, call
gui_main() - Native type mapping —
str,int,float,bool,list,dict,Enum→ widgets automatically - Async execution — every tool runs in a thread; stdout and
loggingare captured in real time - Execution history — every run is persisted to SQLite with parameters, logs, and status
- Replay — restore any past run's parameters with one click
- Light theme — clean built-in stylesheet, Consolas / 微软雅黑 / Meiryo font stack
Installation
pip install decoui
Requires Python 3.10+ and PySide6 6.6+.
Quick Start
import logging
from decoui import tool, toolset, gui_main
@toolset(label="Text Tools", tags=["text"])
class TextTools:
@tool(label="Count Characters",
description="Count chars, words and lines.",
placeholders={"content": "Paste text here…"})
def count(self, content: str = "") -> str:
words = len(content.split())
logging.info("words=%d", words)
return f"{len(content)} chars / {words} words"
if __name__ == "__main__":
gui_main(title="My Tools")
gui_main() auto-discovers every @toolset class in the caller's global scope — no explicit registration needed.
API Reference
@toolset
Applied to a class. Groups its @tool methods under one sidebar entry.
@toolset(
label="CSV Tools", # required — sidebar display name
tags=["file", "batch"], # optional — used by the tag filter bar
description="...", # optional — tooltip on hover in the sidebar
)
class CsvTools:
...
| Parameter | Type | Description |
|---|---|---|
label |
str |
Required. Display name in the sidebar. |
tags |
list[str] |
Tag filter bar labels. Multiple tags = AND filter. |
description |
str |
Shown as a tooltip when hovering the toolset in the nav tree. |
@tool
Applied to a method inside a @toolset class.
@tool(
label="Merge Files",
description="Merge multiple files into one.",
placeholders={"files": "one path per line"},
confirm=True, # show confirmation dialog before running
timeout=120, # cancel after N seconds (None = unlimited)
)
def merge(self, files: list, output: str = "out.txt") -> str:
...
| Parameter | Type | Default | Description |
|---|---|---|---|
label |
str |
required | Tool display name. |
description |
str |
"" |
Shown in a bordered box below the title. |
placeholders |
dict[str,str] |
{} |
Placeholder text per parameter name. |
confirm |
bool |
False |
Show a Yes/No confirmation dialog before running. |
timeout |
int|None |
None |
Execution timeout in seconds. |
gui_main
gui_main(title="My App", db_path="~/.myapp/history.db")
| Parameter | Type | Default | Description |
|---|---|---|---|
title |
str |
"decoui" |
Window title. |
db_path |
str|Path|None |
~/.decoui/history.db |
SQLite database path for execution history. |
Type → Widget Mapping
| Python annotation | Widget | Notes |
|---|---|---|
str |
QLineEdit |
Single-line text. |
int |
QSpinBox |
Integer, full int range. |
float |
QDoubleSpinBox |
4 decimal places. |
bool |
QCheckBox |
Checked / unchecked. |
list |
QTextEdit |
One item per line or comma-separated. |
dict |
QTextEdit |
JSON input; parsed with json.loads then ast.literal_eval. Raises on invalid input. |
Enum subclass |
QComboBox |
Dropdown of enum members. |
pathlib.Path |
QLineEdit + buttons |
Text field with File... (file picker) and Folder... (directory picker) buttons. The selected path is passed as a pathlib.Path to the method. |
- Required parameters (no default) are marked with a red
*in the form label. Optional[X]is unwrapped toX.- Default values are pre-filled into widgets automatically.
pathlib.Path example
import pathlib
from decoui import tool, toolset
@toolset(label="File Tools")
class FileTools:
@tool(label="File Info", placeholders={"path": "Select a file or folder…"})
def file_info(self, path: pathlib.Path) -> None:
import logging
p = pathlib.Path(path)
logging.info("size: %d bytes", p.stat().st_size)
logging.info("resolved: %s", p.resolve())
Output & Logging
Tool methods can use print() and the standard logging module. Both are captured and rendered in the output console with colour coding:
| Source | Colour |
|---|---|
print / stdout |
White |
logging.DEBUG |
Gray |
logging.INFO |
Cyan |
logging.WARNING |
Yellow |
logging.ERROR |
Red |
logging.CRITICAL |
Bold Red |
Return values from tool methods are not displayed in the GUI. Use logging or print for any output you want users to see.
Tool Page Buttons
| Button | Action |
|---|---|
| Run | Type-coerce parameters, run the method in a background thread. |
| Reset | Expand the parameter panel and clear the output console. Parameters are kept. |
| Stop | Request cancellation of the running task. |
| Replay | Open the History panel pre-filtered to this tool's past runs. |
| Copy | Copy current console output to clipboard. |
| View Log | Open the current console output in a resizable log viewer window. |
Execution History
Every run is stored in SQLite. The History panel (sidebar button) shows:
- Timestamp, tool name, status badge, duration
- Per-row checkboxes with Select All / Deselect All / Delete Selected
- Filter by tool, status, and time range
- Click any row to see the parameter snapshot
- Replay Params — restores that run's parameters to the tool's form
- View Full Log — opens the full log in a resizable window with level filters and search
History is stored at ~/.decoui/history.db by default. Override with db_path in gui_main().
Example
See src/decoui/example.py for a complete demo covering all supported widget types.
Run it with:
uv run python main.py
# or
python main.py
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
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 decoui-0.1.3.tar.gz.
File metadata
- Download URL: decoui-0.1.3.tar.gz
- Upload date:
- Size: 428.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f34c0d3cbba821f1db8469d4a4f0bb0df5175ebb75897c5fb86fd0caa8bfb68f
|
|
| MD5 |
25a4d616d26b53ac4e69967869660299
|
|
| BLAKE2b-256 |
7a57dff9c4b2dfea533a46ded3465b9013d6cc3c184634d4ca89d67673d934e5
|
File details
Details for the file decoui-0.1.3-py3-none-any.whl.
File metadata
- Download URL: decoui-0.1.3-py3-none-any.whl
- Upload date:
- Size: 114.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e1060465f7a042d14a1196a342e2640fe035ca498d128d8cfb69e9a725c1a457
|
|
| MD5 |
ef09ac4cb9bedc201063f6b67115e993
|
|
| BLAKE2b-256 |
460cc12b00042a7228ae6355eefac004c31879dce0a17fa8096ec75f5102e251
|