Skip to content
Advertisement

How to use GTK4 without using the `Application` class?

Note how this application implements a mainloop by the activate signal and .run() method call:

import gi
gi.require_version("Gtk", "4.0")
from gi.repository import Gtk

def on_activate(app):
    win = Gtk.ApplicationWindow(application=app)
    btn = Gtk.Button(label="Hello, World!")
    btn.connect('clicked', lambda x: win.close())
    win.set_child(btn)
    win.present()

app = Gtk.Application(application_id='org.gtk.Example')
app.connect('activate', on_activate)
app.run(None)

Correct me: I think this activate signal is emitted as an event to synchronise the creation of GTK windows, widgets, etc, so that the GUI part does not race to happen before the application is ready. What else is the point?

Then, when the Window, widgets, etc are all drawn, the application gets stuck in a mainloop by .run(). This way the application doesn’t exit immediately, but rather waits for user input.

What bothers me here is that I don’t see the value of the Application class. Because of it, we got an event on signal activate to tell “oh the app is ready”, but what is this app anyway? Why can’t I just do .run() on Gtk.ApplicationWindow or even Gtk.Window?

In order to answer those questions above, I invented/discovered this question that, if answered, I think it will address my frustration:

Question: What is the GT4 approach in running GUI apps without using Application or ApplicationWindow classes?


Background

I come from a TKinter background. There, I could make an app simply by saying something like:

import tkinter

class MyApp(tkinter.Tk):
    def __init__(self):
        super().__init__()
        self.title('some title')

if __name__ == '__main__':
    myapp = MyApp()
    myapp.mainloop()

It feels much simpler, without a spaghetti of creating two objects (like in GTK4) with signals emitting through them just to barely get a .run() mainloop.

But I have to use GTK4 for this project, and Tkinter is not an option. So I have to learn the suitable GTK4 for me.

Advertisement

Answer

According to the docs: “GtkApplication is a high-level API for writing applications.

It supports many aspects of writing a GTK application in a convenient fashion, without enforcing a one-size-fits-all model.

Currently, GtkApplication handles GTK initialization, application uniqueness, session management, provides some basic scriptability and desktop shell integration by exporting actions and menus and manages a list of toplevel windows whose life-cycle is automatically tied to the life-cycle of your application. While GtkApplication works fine with plain GtkWindows, it is recommended to use it together with GtkApplicationWindow.”

Source: https://docs.gtk.org/gtk4/class.Application.html

The clasic hello world from Gtk3 will not work on Gtk4

This works:

import gi

gi.require_version("Gtk", "3.0")
from gi.repository import Gtk

win = Gtk.Window()
win.connect("destroy", Gtk.main_quit)
win.show_all()
Gtk.main()

But if you change “3.0” by “4.0” does not work and the reason is on the migration guide:

“GTK 4 removes the gtk_main_* family of APIs. The recommended replacement is GtkApplication”

https://docs.gtk.org/gtk4/migrating-3to4.html#stop-using-gtk_main-and-related-apis

Gtk have a different approach to Tk, you will need to be used to that.

And GTK4 is still new, you will found more examples about Gtk3 code, so, keep the migration guide at hand

User contributions licensed under: CC BY-SA
6 People found this is helpful
Advertisement