Skip to main content

ViewForge is a minimalist Python UI framework for building desktop apps with web technologies and live reload support.

Project description

ViewForge

ViewForge is a modern Python desktop UI framework that renders HTML and web components inside a pywebview window.

It supports component-based rendering, declarative event registration, reactive state with signals, and flexible routing — all in Python.


✨ Features

  • ✅ Component-based architecture (Text, Button, Stack, etc.)
  • 🔗 Declarative event binding via @handler()
  • 🧠 Central Python event router for dynamic dispatch
  • 🧩 Flexible styling via CSS-style dicts
  • 🌐 Built-in router with support for path params and query strings
  • ⚡ Hot reload with Ctrl+R
  • 🔁 Signals for reactive state
  • 📦 Modular, extensible, no build step required

📁 Project Structure

viewforge/
├── core/             # App, Component, Registry
├── ui/               # elements/, layout/, links/
├── routing/          # route decorators, RouterView
├── state/            # Signal, Store
├── rendering/        # DOM and HTML rendering logic
├── utils/            # CSS, JS utilities, case handling
├── adapters/         # Optional UI system adapters (Shoelace, BeerCSS)
├── plugins/          # Debug tools, hot reload
└── main.py           # App entry point

🚀 Getting Started

1. Define a handler

from viewforge.core.registry import handler

@handler()
def handle_click():
    print("Button clicked!")

2. Use the handler in a Button

from viewforge.ui.elements import Button

Button("Click Me", on_click=handle_click)

3. Launch the app

from viewforge.core import App

App().run(lambda: [Button("Hi")])

🧠 How Events Work

  • You define Python handlers with @handler() → they get a unique name like on_handle_click

  • Components like Button render HTML like:

    <sl-button onclick="vf('on_handle_click')">Click</sl-button>
    
  • The global vf(...) JS function relays to Python via pywebview.api.handle_event(...)

  • The Python router calls your function:

    def handle_event(self, name, *args):
        return handler_registry.get()[name](*args)
    

🌐 Routing Example

from viewforge.routing import route

@route("/user/<id>", "User Profile")
def user_profile(params, route):
    return Text(f"Viewing user {params['id']}")

💡 Signals

from viewforge.state import Signal

count = Signal(0)

Button("Increment", on_click=lambda: count.set(count.get() + 1))
Text(lambda: f"Count: {count.get()}")

🔧 Advanced Tips

  • All components support style={} for CSS properties
  • You can nest layout containers like Stack, Box, or build your own
  • Router supports dynamic segments and query strings

📦 Coming Soon

  • ✅ FormGroup with validation
  • 🧭 View decorators for route views
  • 🌈 Light/dark theme switching

🧼 Philosophy

ViewForge is minimal by design — no JavaScript build steps, no virtual DOM diffing — just clean Python and direct HTML rendering.

Build UIs in Python. Render like the web.

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

viewforge-0.1.0.dev2.tar.gz (30.0 kB view details)

Uploaded Source

Built Distribution

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

viewforge-0.1.0.dev2-py3-none-any.whl (36.6 kB view details)

Uploaded Python 3

File details

Details for the file viewforge-0.1.0.dev2.tar.gz.

File metadata

  • Download URL: viewforge-0.1.0.dev2.tar.gz
  • Upload date:
  • Size: 30.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.3

File hashes

Hashes for viewforge-0.1.0.dev2.tar.gz
Algorithm Hash digest
SHA256 f0aa2078d892ef0cd1f437d34f6b9f1b94b148e09593d0b4d1cfc4389efa6ee0
MD5 635bc922f14f9f89e881200125114000
BLAKE2b-256 66af77dccee88228b1ddc9000e074f643c0327bc0582e0ac3363881f32bfbb59

See more details on using hashes here.

File details

Details for the file viewforge-0.1.0.dev2-py3-none-any.whl.

File metadata

  • Download URL: viewforge-0.1.0.dev2-py3-none-any.whl
  • Upload date:
  • Size: 36.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.3

File hashes

Hashes for viewforge-0.1.0.dev2-py3-none-any.whl
Algorithm Hash digest
SHA256 58c385cde19309e67f5440b157f12f498cdc950e3c6dcd1b73ba1d7b14337524
MD5 bc704e2268226c0a887b7fd90c60f891
BLAKE2b-256 2af03bef4cc11fedf551cad59dc53c6c7350404ad8bd8e985114941f3071d573

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