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.0a1.tar.gz (28.3 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.0a1-py3-none-any.whl (23.9 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: oneforall_gui-0.1.0a1.tar.gz
  • Upload date:
  • Size: 28.3 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.0a1.tar.gz
Algorithm Hash digest
SHA256 22d24b1c071cfef67b7fb0c6d07568e332db6d20fe598b69043a5a58d57c54c2
MD5 2bcebf1bab410296400359382832df9b
BLAKE2b-256 2d7fb957564e2c0c4b148519681bac22c824c5856d611c7bdc0969e7618f6939

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for oneforall_gui-0.1.0a1-py3-none-any.whl
Algorithm Hash digest
SHA256 72fc862902acff20cf83c4d88802fe2b7a5fc0ef4b62a1a561a798379323c7fc
MD5 bff906be2426e17cf1f44bba2c280ef5
BLAKE2b-256 805f09fd6ce1b1beb17053ec8b6d08f617032c14f93017484d0e8041022ef20e

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