Skip to main content

OneForAll — lightweight Python GUI toolkit using pywebview and Python-only components.

Project description

OneForAll

Build desktop apps with Python and Tailwind CSS.

Installation

pip install oneforall

Quick Start

Create a new app:

oneforall init my_app
cd my_app
oneforall dev example_basic.py

Basic Example

from oneforall import App, Window
from oneforall.components import Container, Text, Button

# Create app and window
app = App()
window = Window(title="My App", size=(600, 400))

# Create container
container = Container(className="p-8 space-y-4")

# Add text
title = Text("Hello, World!", className="text-2xl font-bold text-blue-600")
container.add(title)

# Add button with click handler
def handle_click():
    title.text = "Button was clicked!"

button = Button(
    "Click Me", 
    on_click=handle_click,
    className="px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600"
)
container.add(button)

# Add container to window and run
window.add_child(container)
app.windows.append(window)

if __name__ == "__main__":
    app.run(dev_mode=True)

Components

Text

text = Text("Hello", className="text-lg font-bold")

Button

def click_handler():
    print("Clicked!")

button = Button("Click Me", on_click=click_handler, className="px-4 py-2 bg-blue-500 text-white rounded")

Container

container = Container(className="p-4 space-y-2")
container.add(text)
container.add(button)

Styling

OneForAll uses Tailwind CSS for styling. All Tailwind classes work:

# Flexbox layout
container = Container(className="flex items-center justify-center h-screen")

# Styling text
title = Text("Welcome", className="text-3xl font-bold text-gray-800")

# Button variants
primary_btn = Button("Primary", className="bg-blue-500 hover:bg-blue-600 text-white px-4 py-2 rounded")
danger_btn = Button("Delete", className="bg-red-500 hover:bg-red-600 text-white px-4 py-2 rounded")

State Management

Use built-in state for dynamic UIs:

app = App()

# Initialize state
counter = app.use_state('counter', 0)

# Create UI
count_text = Text(f"Count: {counter}", className="text-xl")

def increment():
    current = app.use_state('counter', 0)
    app.set_state('counter', current + 1)

button = Button("Increment", on_click=increment)

CLI Commands

Development

oneforall dev example_basic.py          # Run with hot reload

Project Setup

oneforall init my_project      # Create new project

Build

oneforall build example_basic.py        # Create executable

Example Apps

Counter App

from oneforall import App, Window
from oneforall.components import Container, Text, Button

app = App()
window = Window(title="Counter", size=(300, 200))
container = Container(className="p-8 text-center space-y-4")

count = app.use_state('count', 0)
count_display = Text(f"Count: {count}", className="text-2xl font-bold")

def increment():
    current = app.use_state('count', 0)
    app.set_state('count', current + 1)

def decrement():
    current = app.use_state('count', 0)
    app.set_state('count', current - 1)

container.add(count_display)
container.add(Button("+", on_click=increment, className="mx-2 px-4 py-2 bg-green-500 text-white rounded"))
container.add(Button("-", on_click=decrement, className="mx-2 px-4 py-2 bg-red-500 text-white rounded"))

window.add_child(container)
app.windows.append(window)

if __name__ == "__main__":
    app.run(dev_mode=True)

Todo List

from oneforall import App, Window
from oneforall.components import Container, Text, Button

app = App()
window = Window(title="Todo App", size=(400, 500))
container = Container(className="p-6 space-y-4")

todos = app.use_state('todos', ["Learn OneForAll", "Build awesome app"])

# Display todos
for i, todo in enumerate(todos):
    todo_container = Container(className="flex justify-between items-center p-2 bg-gray-100 rounded")
    todo_container.add(Text(todo, className="flex-1"))
    
    def remove_todo(index=i):
        current_todos = app.use_state('todos', [])
        new_todos = current_todos[:index] + current_todos[index+1:]
        app.set_state('todos', new_todos)
    
    todo_container.add(Button("Remove", on_click=remove_todo, className="px-2 py-1 bg-red-500 text-white rounded text-sm"))
    container.add(todo_container)

window.add_child(container)
app.windows.append(window)

if __name__ == "__main__":
    app.run(dev_mode=True)

Custom Components

Create reusable components:

# components/card.py
from oneforall.components import Container, Text

def Card(title, content, className=""):
    card = Container(className=f"p-6 bg-white rounded-lg shadow-md {className}")
    card.add(Text(title, className="text-xl font-bold mb-2"))
    card.add(Text(content, className="text-gray-600"))
    return card

# Use it
from components.card import Card

card = Card(
    title="Welcome", 
    content="This is a custom card component",
    className="max-w-sm mx-auto"
)

Need Help?

License

This project is licensed under the Apache License 2.0.

You are free to use this framework in commercial and non-commercial projects.
Apps built with this framework can be proprietary or open-source.
The project name and branding are owned by Rohit Ahirwal and may not be used
to imply official affiliation without permission.


Built by Rohit Ahirwal

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

oneforall_gui-0.1.0a2.tar.gz (28.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

oneforall_gui-0.1.0a2-py3-none-any.whl (24.8 kB view details)

Uploaded Python 3

File details

Details for the file oneforall_gui-0.1.0a2.tar.gz.

File metadata

  • Download URL: oneforall_gui-0.1.0a2.tar.gz
  • Upload date:
  • Size: 28.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.7

File hashes

Hashes for oneforall_gui-0.1.0a2.tar.gz
Algorithm Hash digest
SHA256 891b1194ce1f76799611f5d55e6bb4d5425bd1af323b0e95f942413fa980ac91
MD5 557b9f56d66db14445da0952bcc106bb
BLAKE2b-256 1f69e3d7ce96a25f4d39789110917459262b64af752316a1880ae2bab4855fec

See more details on using hashes here.

File details

Details for the file oneforall_gui-0.1.0a2-py3-none-any.whl.

File metadata

File hashes

Hashes for oneforall_gui-0.1.0a2-py3-none-any.whl
Algorithm Hash digest
SHA256 2d5463e96563204912f7585e8ca084b392141a40a987e96f5241c9f800145adf
MD5 d74bea2f55a4f1864f875991af22ec24
BLAKE2b-256 34421a020d8b67461f71fd79cf37104c0f081e122dfe23b957ad83cbe38bab3e

See more details on using hashes here.

Supported by

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