PyGTK Overview
PyGTK is the Python binding for the GTK+ 2 toolkit - the library that powers the GNOME desktop and, for fifteen years, was the default way to build a native GUI in Python. It binds the C library to Python with the pygobject layer, so every GTK widget, signal, and style property is available as a Python object with an idiomatic calling convention: gtk.Button() instead of gtk_button_new(), button.connect("clicked", handler) instead of a function-pointer callback. This chapter orients the tutorial: what PyGTK is, the object model it exposes, the main-loop architecture every GTK app runs on, and where PyGTK sits in the current Python-GUI landscape.
What PyGTK Is
import gtk
# the version introspection - pygtk reports the bound GTK version
print(gtk.gtk_version()) # (2, 24, 30) - GTK+ 2.24 series
# the binding itself: the pygtk 2.x series
# pygtk 2.10 -> GTK+ 2.0
# pygtk 2.24 -> GTK+ 2.24 (the final GTK 2 series, and the final
# release line of PyGTK itself)
# the import name "gtk" is the binding; the C library behind it
# is libgtk-2.0
PyGTK is a binding, not a toolkit: the widgets, the rendering, the windowing, and the event system all come from GTK+ 2 (itself built on GDK, the platform layer, and on Pango/Cairo for text and drawing). The binding adds the Python object model - classes with methods, signals connected to Python functions, properties set with attribute-style calls - and the glue that keeps the C event loop and the Python callback world compatible. The practical consequence is that a PyGTK app is a GTK app: it looks native on the GNOME desktop, uses the system icon theme and widget style, and behaves like every other GTK application, while the code stays in Python.
The Object Model and the Main Loop
import gtk
# the three-part shape of EVERY PyGTK program:
# 1. build the widget tree (the UI)
window = gtk.Window(gtk.WINDOW_TOPLEVEL)
window.set_title("Hello")
button = gtk.Button(label="Quit")
window.add(button)
# 2. wire the behavior (signals)
def on_quit(widget):
gtk.main_quit()
button.connect("clicked", on_quit)
# 3. enter the main loop (it does not return until quit)
window.show_all()
gtk.main()
Every PyGTK program has the same three-part shape, and recognizing it is the orientation skill. Build the widget tree - a parent window, the child widgets added into containers, the whole hierarchy assembled in memory. Wire the behavior - the signal connections, where a named event (clicked, delete-event, expose-event) is bound to a Python function with its data. Enter the main loop - gtk.main() runs the event loop: it receives OS events (input, exposure, timer), dispatches them to the widget that owns them, and returns only when gtk.main_quit() is called. The loop owns the process: a PyGTK app that has not entered the main loop is a UI that cannot respond, and one that has quit is done.
Signals: The Behavior Model
import gtk
# a signal is a named event; connecting binds a handler to it
window = gtk.Window()
# the handler signature: (widget, *signal_specific_args)
def on_delete(widget, event):
# returning True means "handled" - the window will not close
# unless the handler calls gtk.main_quit() itself
print("close requested, event:", event.type)
return False # False = default action proceeds (the window closes)
window.connect("delete-event", on_delete)
# signals carry the widget that fired as the first argument,
# then the signal-specific payload (an event object, a response id,
# an index - depending on the signal)
The signal is the behavior model, and it is the single most important concept in the toolkit: widgets do not call your code through Python callbacks in the ordinary sense, they emit named signals, and your handlers attach to those names. The handler receives the emitting widget first, then the signal-specific arguments (the event object for input events, a response id for dialog responses, the page index for notebook switches). For events with a default action - delete-event closes the window, key-press-event propagates to the parent - the handler's return value decides whether the default still runs, and that boolean discipline is one of the things the signals chapter covers in detail. The model is the reason GTK scales: the widget does not know who listens, several handlers can attach to one signal, and the connection is data (connect/disconnect) rather than code structure.
Where PyGTK Sits Today
PyGTK's place in history is clear: it was the standard Python GUI binding from the early 2000s through the 2010s, and it is the binding this tutorial teaches because a large installed base of desktop applications still runs on it and because its concepts - the widget tree, the signals, the main loop, the containers - are the concepts the modern stack inherited. The modern stack is PyGObject (the gi introspection bindings) on GTK 3 and GTK 4, where from gi.repository import Gtk replaces import gtk and the same architectural patterns carry over with updated spelling. PyGTK itself is in maintenance-only history - the last GTK 2 series it binds is still widely deployed, but new development has moved to the introspection-based binding, and the later chapters of this tutorial cover the transition and the choice explicitly. The orientation to hold: learn the GTK architecture through PyGTK, and the migration chapter shows exactly what changes when the binding changes.
Summary
PyGTK is the Python binding for the GTK+ 2 toolkit: the widgets and the event system come from GTK+ 2, and the binding provides the Python object model - widget classes, signal connections, and the gtk.main() event loop. Every program has the three-part shape - build the widget tree, wire the signals, enter the main loop - and the signal is the behavior model: named events with handlers that receive the widget and the event payload, with return values controlling the default action on certain events. PyGTK is the historical standard of the Python-GUI era, now in maintenance, with the modern stack being PyGObject on GTK 3/4 - the transition and the choice are the subject of the dedicated chapters, but the architecture learned here is the architecture that carries over.