Question

I am new to GTK and I stumbled upon a problem which sounds simple but I just can't find a way to deal with it. Basically, calling gtk.main() makes my single-threaded process halt. I know that gtk.main() is blocking, but I have not called gtk.main() any time before so quitting the main loop will not do any good since there is no loop to quit from.

Even so, gtk.main_level() returns 0. Moreover, when I try gtk.main() from the python command line, it hangs as well. There is something basic I am missing, so can anybody point me to it? Appreciated.

EDIT: The Gtk method I need is gobject.add_timeout, like this:

gobject.timeout_add(2000, callback)
gtk.main() # This blocks the thread.
Was it helpful?

Solution

It looks like it is blocking the application, but what is doing is processing events. One of the events has to terminate the loop. You can check the idea behind the event loops in Wikipedia.

If you do not want to program a graphical interface, then you do not need Gtk, you only need Glib. Here an example to show you how the main loop works (the concept is similar in Gtk and Glib):

from gi.repository import GLib, GObject

counter = 0

def callback(*args):
    global counter
    counter += 1
    print 'callback called', counter
    if counter > 10:
        print 'last call'
        return False

    return True

def terminate(*args):
    print 'Bye bye'
    loop.quit()

GObject.timeout_add(100, callback)
GObject.timeout_add(3000, terminate)
loop = GLib.MainLoop()
loop.run()

If the callback returns False, then it will be removed and not called anymore. If you want the callback to be called again, it has to return True (as you can see in the function callback).

I set another callback terminate to show how to quit from the loop. If you do not do it explicitly, then GLib will continue waiting for more events (It does not have any way to know what you want to do).

With the PyGTK (old and deprecated), the code will be:

import gobject, glib, gtk

counter = 0

def callback(*args):
    global counter
    counter += 1
    print 'callback called', counter
    if counter > 10:
        print 'last call'
        return False

    return True

def terminate(*args):
    print 'Bye bye'
    loop.quit()

gobject.timeout_add(100, callback)
gobject.timeout_add(3000, terminate)
loop = glib.MainLoop()
loop.run()

OTHER TIPS

I encountered the same problem then I add this gtk.gdk.threads_init() before call gtk.mainloop(). It works fine with me

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top