Proper way of building Gtk3 applications in Python

Michał Tabor picture Michał Tabor · Jan 3, 2014 · Viewed 8.8k times · Source

I have just started learning about creating GUI apps in Python. I decided to use Gtk version 3. According to the (official?) tutorial on http://python-gtk-3-tutorial.readthedocs.org/ the proper way of building a hello world application is:

from gi.repository import Gtk

class MyWindow(Gtk.Window):
    def __init__(self):
        Gtk.Window.__init__(self)
        self.set_default_size(200, 100)
        self.connect('destroy', Gtk.main_quit)
        self.show_all()

MyWindow()
Gtk.main()

In other tutorial (http://www.micahcarrick.com/gtk3-python-hello-world.html) I found completly different aproach which is:

from gi.repository import Gtk, Gio

class HelloWorldApp(Gtk.Application):
    def __init__(self):
        Gtk.Application.__init__(self, application_id="apps.test.helloworld",
                                 flags=Gio.ApplicationFlags.FLAGS_NONE)
        self.connect("activate", self.on_activate)

    def on_activate(self, data=None):
        window = Gtk.Window(type=Gtk.WindowType.TOPLEVEL)
        window.set_title("Gtk3 Python Example")
        window.set_border_width(24)
        label = Gtk.Label("Hello World!")
        window.add(label)
        window.show_all()
        self.add_window(window)

if __name__ == "__main__":
    app = HelloWorldApp()
    app.run(None)

Could someone experienced in this category tell me in what way should I write Gtk 3 apps in python these days? I'm already familiar with writing GUIs (spent few months in Java's Swing) so you can go on with terms like events, callbacks and so on..

Answer

ilent2 picture ilent2 · Jul 19, 2015

Choosing to write your new program with a GtkApplication or just a GtkWindow depends on the functionality you require, and to some extent the intended audience.

For most cases, especially when you are still learning the toolkit, I would tend to agree with valmynd that GtkApplication is unnecessarily complicated. GtkApplication provides a lot of extra functionality that you probably don't want or need in smaller applications.

For larger, more complete applications I agree with Dragnucs, the second approach is superior and can provide better integration into the desktop environment. From GNOME Goal: Port to GtkApplication (see also the GtkApplication docs):

Porting your application to use GtkApplication has quite nice benefits: 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.

However I disagree with Dragnucs about why the GtkWindow approach is introduced in the tutorial. I tend to think simple examples with very little boilerplate are more appropriate for a tutorials Getting Started section (but, I do think that the read-the-docs tutorial needs to be updated to include at least some mention of GtkApplication).

In applications I've written I tend to either subclass both GtkApplication and GtkWindow or for single window quick-and-nasty applications just subclass GtkWindow. Your decision will depend on your applications needs.

Technical difference: There is also an important technical difference between how the two examples are implemented. The example with just a GtkWindow creates a new Gtk main loop for each instance of the program. The example with GtkApplication creates a single main loop attached to the first instance and each subsequent call to run(None) will request that the original instance create a new window (the new instance will then exit). Try opening up two terminals and running your application in each window, notice that one terminal will wait until all the windows have closed before becoming sensitive again. You can change this behaviour by using G_APPLICATION_NON_UNIQUE instead of G_APPLICATION_FLAGS_NONE.