OmniNative UI
OmniNative UI is a user interface framework for Python built on top of PySide6. It brings the declarative and reactive development paradigm (like React, SwiftUI, or Flutter) to the native desktop application ecosystem.
Forget about the verbosity of instantiating widgets, passing manual parents, and connecting signals by hand. With OmniNative UI, you define your visual hierarchy using Context Managers (with) and let a Flexbox engine and reactive states do the heavy lifting.
✨ Key Features
- 🔄 Native Reactivity (Two-Way Data Binding): Connect your app's state to the UI using
OStateandOComputed. When data changes, the interface updates automatically. - 📐 Flexbox Layout Engine: Use
HStack,VStack, andCardwith properties likeflex_grow,flex_shrink, andflex_basisto build responsive UIs without fighting withQBoxLayout. - 🧩 Declarative Syntax (
with): Your Python code indentation represents the exact visual tree of your application. Cleanly coupled via Python Context Managers. - 🌉 Full Interoperability (
ONative): Have a complex pure PySide6 widget from another library? Wrap it inONative()and it will integrate seamlessly into your declarative tree and Flexbox system. - 🗑️ Smart Memory Management: Proactive Garbage Collection (GC) using C++ signals that automatically clean up reactive state subscriptions, preventing memory leaks.
- 🎬 Declarative Animations: Inject fluid micro-interactions (fade, slide, scale) directly into your widgets using a simple
.animate()method, or automate enter/exit transitions inOConditional. - 🎨 Premium Dark Theme: Modern and consistent aesthetics out-of-the-box without writing a single line of QSS/CSS.
🚀 The Declarative Shift: Before vs. Now
The best way to understand the power of OmniNative UI is to see how the same code is written.
The traditional PySide6 way (Imperative):
group = QFrame()
layout = QHBoxLayout(group)
label = QLabel("Counter: 0")
button = QPushButton("Increment")
layout.addWidget(label)
layout.addWidget(button)
parent_layout.addWidget(group)
The OmniNative UI way (Declarative & Reactive):
counter = OState(0)
with HStack():
OLabel(text=counter) # Updates automatically when 'counter' changes
OButton(text="Increment", primary=True, command=lambda: counter.set(counter.get() + 1))
💡 Why OmniNative UI?
For Human Developers
- Goodbye Boilerplate: Stop writing boilerplate code for signal connections, widget instantiation, and manual state mutations. The UI is a direct reflection of your state. Change the
OState, and the UI updates itself. - Web Mentality on Desktop: OmniNative UI brings a modern web-like development experience (like React, SwiftUI, and CSS Flexbox) to compiled C++ desktop apps. You build robust native desktop software using the mental models of modern web development.
- Zero Memory Leaks: Proactive Garbage Collection seamlessly handles the cleanup of reactive state subscriptions when a widget dies, completely neutralizing the notorious C++ memory leaks hidden in Python.
For AI Agents & LLMs
- Structural Context: LLMs write perfect declarative code because the component tree is semantically tied to Python's indentation (via Context Managers). It writes like HTML, avoiding the spaghettification that occurs when AI tries to track imperative variables (
label1,layout2) across hundreds of lines. - One-Shot Generation: The API is reduced to simple declarative props (
flex_grow=1,primary=True), drastically minimizing AI hallucinations of obscure Qt C++ methods.
💻 Quick Start
Install the package directly from PyPI:
pip install omninative-ui
Create your first reactive app in less than 10 lines:
import sys
from PySide6.QtWidgets import QApplication
from omninative_ui import OWindow, OLabel, OButton, HStack, OState
app = QApplication(sys.argv)
# Shared reactive state
click_count = OState(0)
with OWindow(title="My Reactive App", width=400, height=200) as window:
with HStack(pad=20):
OLabel(text=click_count, bright=True, size=16)
OButton(text="Click", primary=True, command=lambda: click_count.set(click_count.get() + 1))
window.omninativeui_reveal_when_ready()
window.show()
sys.exit(app.exec())
🌉 PySide6 Interoperability
You are not locked in. You can mix native Qt widgets directly into your declarative flow using the ONative wrapper:
from PySide6.QtWidgets import QPushButton, QCalendarWidget
from omninative_ui import HStack, OLabel, Spacer, ONative
with HStack():
OLabel("Select a date:")
Spacer()
# 100% native PySide6 widgets integrated into the Flexbox layout
ONative(QPushButton("Native Button"))
ONative(QCalendarWidget(), flex_grow=1)
📊 Data-Driven Reactive Tables
Handling complex data tables in Python has never been easier. OVirtualTable connects directly to an OState list of dictionaries and supports custom widget injection per cell.
table_data = OState([
{"id": 1, "status": "Active"},
{"id": 2, "status": "Pending"}
])
def render_action_cell(row_data):
def delete_item():
table_data.set([item for item in table_data.get() if item["id"] != row_data["id"]])
return OButton(text="Delete", small=True, danger=True, command=delete_item)
OVirtualTable(
data=table_data,
columns={
"id": {"title": "ID", "width": 50},
"status": {"title": "Status", "width": 100},
"action": {"title": "Action", "render_func": render_action_cell}
}
)
When table_data mutates, the table re-renders automatically, cleaning up old widgets safely.
📖 Documentation
For full API references, architecture guides, and instructions on creating your own declarative components, check out the Full Documentation (/docs/INDEX.md).
🤖 For AI Agents
If you are an Autonomous Agent or AI Assistant tasked with building an application using OmniNative UI, you can use the AI Instruction Manual (docs/AI_PROMPT.md) as your system prompt. It contains all the necessary context and rules to write perfect declarative code out of the box.
🧩 Components
Layouts & Reactivity
| Component | Description |
|---|---|
OState |
Reactive state for two-way data binding. |
OComputed |
Derived state that updates when its dependencies change. |
OConditional |
Reactive conditional rendering (Show/Hide based on OState). |
ORepeater |
Reactive list rendering. Iterates over an OState list and dynamically repaints children when data mutates. |
HStack / VStack |
Horizontal and vertical containers powered by the Flexbox engine. |
Card |
Styled container with padding and rounded corners. |
ONative |
Wrapper to inject pure PySide6 widgets into the declarative tree. |
Core & Inputs
| Component | Description |
|---|---|
OWindow |
Main window with OmniNative theme. |
OButton |
Button with variants (primary, danger) and micro-interactions. |
OLabel / OElidedLabel |
Text labels capable of binding to OState. |
OComboBox |
Custom floating dropdown. |
OLineEdit / OTextBox |
Text input fields. |
OSlider / OSpinBox |
Interactive numeric controls. |
Advanced Containers & Data
| Component | Description |
|---|---|
OScrollArea |
Responsive scrollable area. |
OTabs / OTab |
Declarative tab navigation. |
OTreeWidget |
Collapsible accordion. |
OVirtualTable |
High-performance, data-driven reactive table. Accepts an OState list of dictionaries and supports custom declarative widgets per cell via render_func. |
Media & Chat
| Component | Description |
|---|---|
OAudioPlayer |
Audio player with waveform visualization. |
OImageViewer |
Image gallery with fullscreen mode. |
OChatView / OChatInput |
Complete chat interface with Markdown support. |
🤝 Contributing
Pull requests are welcome! For major changes, please open an issue first to discuss what you would like to change.
Please make sure to update the documentation in the docs/ folder as appropriate.
📄 License
LGPL-3.0-only
🎖️ Credits
This project is made possible thanks to:
Metadata
Release files for omninative-ui 1.0.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| omninative_ui-1.0.1.tar.gz | 61.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| omninative_ui-1.0.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 126.5 kB
Release files / omninative_ui-1.0.1.tar.gz
| Download URL | omninative_ui-1.0.1.tar.gz |
|---|---|
| Size | 61.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
33e98c0910d8501cc0df48e0c84100d5c0b360c9fc79502b00773b881c1e1fcf
|
|
BLAKE2b-256 checksum How to use checksums |
52df6dfe07ccc9f64663ffb080e12466001da68cdb08cce79faafefc41e1e0c2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 5, 2026.
Transparency logRelease files / omninative_ui-1.0.1-py3-none-any.whl
| Download URL | omninative_ui-1.0.1-py3-none-any.whl |
|---|---|
| Size | 64.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
5f86d22b848aabffa12cfb207b1c57b511020b41c9765718fcb3262f7937967d
|
|
BLAKE2b-256 checksum How to use checksums |
2f1c76485a45dca2dfc5e3dfa5998526373524d99d63b13123eab56c1852f066
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 5, 2026.
Transparency log