Sunday, May 22, 2011

GtkWindow Basics

Most GUI are built as windows (actually, I can't think of a GUI that isn't a window even if that window is transparent, like a desklet, it is a window nonetheless). So we should start from there. The GtkWindow widget is a subclass of GtkWidget which in turn is a subclass of Gobject, this is why we'll find our GtkWindow class in the Gtk Module of the Gobject Introspection repository. Code-wise, it looks like so:

from gi.repository import Gtk
w = Gtk.Window()

A window needs few other things to appear onto the screen, here is a minimal example:

#!/usr/lib/python
from gi.repository import Gtk
class WindowApp:
        def __init__(self):
                self.window = Gtk.Window().new(Gtk.WindowType.TOPLEVEL)
                self.window.connect('destroy', lambda x: Gtk.main_quit())
                self.window.set_title('Window')
                self.window.show_all()
               

if __name__ == '__main__':
        app = WindowApp()
        Gtk.main()

That should provide you with a cute Gtk+3 window:

The title bar decoration depends on your window manager, so it may vary. The actual window widget is the area below that title bar. Not on this picture, but you may see it on your screen: there is a resize-grip on the bottom right of the window, we'll see about that later.

Let's look a bit closer at the code:

from gi.repository import Gtk
It should be clear by now that we are importing Gtk from our Gobject Introspection module.

class WindowApp:
We defined a new object class called WindowApp. This object represents our main application, which we instantiate later in the code:

app = WindowApp()


As we define our application in def __init__(self):, we need to reference our main window as self.window which is an instance of our Gtk.Window(), initiated with:
self.window = Gtk.Window().new(Gtk.WindowType.TOPLEVEL)
The new() method specifies our window is a TOPLEVEL window, as opposed to a 'pop up'; the former will be managed by the Window Manager whilst the latter won't. The default is 'top level', hence Gtk.Window() would have been enough indeed.

self.window.connect('destroy', lambda x: Gtk.main_quit())
The above line tells us to stop the Gtk main loop (see below) when the window is destroyed (i.e. when you click on the [x] button on your window decoration / title bar). The Gtk.Window.connect() method is an event-handler method, this means it will be triggered when a signal is emitted--in this instance the 'destroy' signal emitted on closing the window. The second argument in connect() is the method or function we want to call when the signal is received. In this case we used a lambda, but we could have called a method defined as eg. def quitApp(self): ect. More on event-handling later.

self.window.set_title('Window')
With this line we set a title of our title bar.

self.window.show_all()
This method is important: it draws the window (it does not appear until the main loop is launched though). We'll have to be careful later, because some window properties and methods will have to be called before and other after that method. Alternatively we could have used self.window.show(), but show_all() specifies showing the top level window and all its children (i.e. all the other widgets we'll attached to it).

app = WindowApp()
That instantiates our application.

Gtk.main()
This starts the Gtk main loop, without which the interface does not appear and which is a loop allowing to listen for signals emitted by widgets whenever those emit one (typically when clicking on them or when their value changes).
We'll look at more details on the GtkWindow next time.

No comments:

Post a Comment