https://github.com/sigmasd/js-gtk-py
Wrapper + types over Gtk using javascript python bindings
https://github.com/sigmasd/js-gtk-py
adwaita deno gtk python
Last synced: 2 months ago
JSON representation
Wrapper + types over Gtk using javascript python bindings
- Host: GitHub
- URL: https://github.com/sigmasd/js-gtk-py
- Owner: sigmaSd
- License: mit
- Created: 2023-11-09T20:12:01.000Z (over 2 years ago)
- Default Branch: master
- Last Pushed: 2025-12-25T08:42:39.000Z (6 months ago)
- Last Synced: 2025-12-26T21:45:42.591Z (6 months ago)
- Topics: adwaita, deno, gtk, python
- Language: TypeScript
- Homepage: https://jsr.io/@sigma/gtk-py
- Size: 212 KB
- Stars: 2
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# JS Gtk Py
Wrapper + types over Gtk using javascript python bindings
## Usage
```ts
#!/usr/bin/env -S JS -A
import {
type Adw1_ as Adw_,
type GLib2_ as GLib_,
type Gtk4_ as Gtk_,
JSGLibEventLoop,
kw,
NamedArgument,
python,
} from "jsr:@sigma/gtk-py";
const gi = python.import("gi");
gi.require_version("Gtk", "4.0");
gi.require_version("Adw", "1");
const Gtk: Gtk_.Gtk = python.import("gi.repository.Gtk");
const Adw: Adw_.Adw = python.import("gi.repository.Adw");
const GLib: GLib_.GLib = python.import("gi.repository.GLib");
// Use JSGLibEventLoop to keep JS's event loop running
// This allows setTimeout, fetch, and other JS APIs to work normally
const eventLoop = new JSGLibEventLoop(GLib);
class MainWindow extends Gtk.ApplicationWindow {
#button;
constructor(kwArg: NamedArgument) {
super(kwArg);
this.set_title("Demo");
this.connect("close-request", () => {
eventLoop.stop();
});
this.#button = Gtk.Button(kw`label=${"Click Me"}`);
this.#button.connect(
"clicked",
python.callback(() => {
const dialog = Adw.MessageDialog(
new NamedArgument("transient_for", this),
new NamedArgument("heading", "JS GTK PY"),
new NamedArgument("body", "Hello World"),
);
dialog.present();
setTimeout(() => {
dialog.close();
}, 1000);
}),
);
this.set_child(this.#button);
}
}
class App extends Adw.Application {
#win: MainWindow | undefined;
constructor(kwArg: NamedArgument) {
super(kwArg);
this.connect("activate", this.onActivate);
}
onActivate = python.callback((_kwarg, app: Gtk_.Application) => {
this.#win = new MainWindow(new NamedArgument("application", app));
this.#win.present();
});
}
const app = new App(kw`application_id=${"com.example.com"}`);
await eventLoop.start(app);
```
Check out the examples directory

## Tips
- The `JSGLibEventLoop` is the recommended way to run GTK apps. It integrates
GLib's event loop with Javascript, allowing `setTimeout`, `fetch`, and other
APIs to work normally alongside your GTK UI.
- **Alternative**: Use `app.run()` for the traditional blocking GTK event loop.
Note that javascript APIs like `setTimeout` won't work in this mode. You'll
need to use GLib primitives like `GLib.timeout_add` instead.
- For running async subprocesses, check out `Gio.Subprocess`
## Random apps made with it
- https://github.com/sigmaSd/Stimulator
- https://github.com/sigmaSd/chrono
## References
- python gtk4 docs: http://lazka.github.io/pgi-docs/
- gtk4 docs: https://docs.gtk.org/gtk4/