Metadata-Version: 2.4
Name: pgwidgets-python
Version: 0.1.3
Summary: Python bindings for the pgwidgets JavaScript widget library
Author: PGWidgets Developers
License: BSD-3-Clause
Project-URL: Homepage, https://github.com/naojsoft/pgwidgets-python
Project-URL: Repository, https://github.com/naojsoft/pgwidgets-python
Keywords: widgets,ui,gui,websocket,browser
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: BSD License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: User Interfaces
Requires-Python: >=3.12
Description-Content-Type: text/markdown
License-File: LICENSE.md
Requires-Dist: pgwidgets-js
Requires-Dist: websockets>=12
Provides-Extra: dev
Requires-Dist: sphinx; extra == "dev"
Requires-Dist: furo; extra == "dev"
Requires-Dist: sphinx-autodoc-typehints; extra == "dev"
Provides-Extra: test
Requires-Dist: pytest; extra == "test"
Dynamic: license-file

# pgwidgets — Python Bindings

Python bindings for the [pgwidgets](https://github.com/naojsoft/pgwidgets-js)
JavaScript widget library. Build desktop-style browser UIs from Python
with a familiar Qt/GTK-style API.

## Installation

```bash
pip install pgwidgets-python
```

This will also install `pgwidgets-js` (the JavaScript assets) and
`websockets` as dependencies.

## Quick Start

```python
from pgwidgets.sync import Application

app = Application()

@app.on_connect
def setup(session):
    Widgets = session.get_widgets()

    top = Widgets.TopLevel(title="Hello", resizable=True)
    top.resize(400, 300)

    vbox = Widgets.VBox(spacing=8, padding=10)
    btn = Widgets.Button("Click me")
    label = Widgets.Label("Ready")

    btn.on("activated", lambda: label.set_text("Clicked!"))

    vbox.add_widget(btn, 0)
    vbox.add_widget(label, 1)
    top.set_widget(vbox)
    top.show()

app.run()
```

Run the script, then open the printed URL in your browser.

## Sync vs Async

Both APIs provide the same widget classes and methods.

**Synchronous** (recommended for most use cases):
```python
from pgwidgets.sync import Application
app = Application()

@app.on_connect
def setup(session):
    Widgets = session.get_widgets()
    btn = Widgets.Button("Click")      # blocking call
    btn.set_text("New text")           # blocking call

app.run()
```

**Asynchronous** (for asyncio applications):
```python
from pgwidgets.async_ import Application
app = Application()

@app.on_connect
async def setup(session):
    Widgets = session.get_widgets()
    btn = await Widgets.Button("Click")    # awaitable
    await btn.set_text("New text")         # awaitable

await app.run()
```

## How It Works

The `Application` class starts two servers:
- An **HTTP server** (default port 9501) that serves the pgwidgets JS/CSS
  and a connector page
- A **WebSocket server** (default port 9500) for the JSON command protocol

When you open the URL in a browser, the page loads pgwidgets and connects
back over WebSocket. Python widget constructors and method calls are
translated to JSON messages and executed in the browser. Callbacks are
forwarded back to Python.

## License

BSD 3-Clause
