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
orApplicationWindow
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