Wrapper + types over Gtk using deno-python
#!/usr/bin/env -S deno run --allow-ffi --allow-env=DENO_PYTHON_PATH --unstable-ffi
import {
type Adw1_ as Adw_,
type Gtk4_ as Gtk_,
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");
class MainWindow extends Gtk.ApplicationWindow {
#button;
constructor(kwArg: NamedArgument) {
super(kwArg);
this.set_title("Demo");
this.#button = Gtk.Button(kw`label=${"Click Me"}`);
this.#button.connect(
"clicked",
python.callback(() => {
Adw.MessageDialog(
//@ts-ignore it is a window
new NamedArgument("transient_for", this),
new NamedArgument("heading", "Deno GTK PY"),
new NamedArgument(
"body",
"Hello World",
),
).present();
}),
);
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"}`);
app.run(Deno.args);
Check out the examples directory
- Gtk have its own loop, somethings that you expect to work might not do to
this, for example
setTimeout
wont work in a python.callback after running Gtk.Applicaiton. The solution is to use the primitives that GLib provides, for example instead ofsetTimeout
, useGLib.add_timeout
- For running async subprocess checkout
Gio.Subprocess
- python gtk4 docs: http://lazka.github.io/pgi-docs/
- gtk4 docs: https://docs.gtk.org/gtk4/