Periodic timers in PyGTK

Posted on April 16, 2010

I've been writing a ton of Python code lately and I'm absolutely loving it. As a C programmer for the better part of the last 15 years, I find the syntax and ease of expression to be refreshing and fun.

I've recently been tasked with writing a GUI interface to an existing product we have at MiserWare called Granola -- a free (as in beer) version of our enterprise power management solution.

I found myself needing a periodic timer to update the window with new statistics coming in from the daemon. You can do this in regular python, but PyGTK, specifically gobject, makes it very easy. Here's an example that draws a simple window with a label displaying the current counter.

#!/usr/bin/env python

import gtk, gobject

class PerodicTimer:
    def __init__(self, timeout):

        # create a simple window with a label
        self.window = gtk.Window()
        self.window.connect('destroy', lambda wid: gtk.main_quit())
        self.window.connect('delete_event', lambda a1,a2:gtk.main_quit())
        vbox = gtk.VBox()
        self.window.add(vbox)
        self.label = gtk.Label('Periodic Timer')
        vbox.pack_start(self.label)
        self.window.show_all()

        # register a periodic timer
        self.counter = 0
        gobject.timeout_add_seconds(timeout, self.callback)

    def callback(self):
        self.label.set_text('Counter: ' + str(self.counter))
        self.counter += 1
        return True

if __name__ == '__main__':
    periodic_timer = PerodicTimer(1)
    gtk.main()

The bulk of the code is just setting up a gtk window, the timer code is only 5 lines or so. As long as callback() returns True, the timer gets re-registered for the original timeout value (1 second in this example). One caveat I found, gobject.timeout_add_seconds() seems to depend on the GTK main loop, so you cannot use it from a regular non-GTK python application.