Search code examples
pythonlinuxgtkpygobject

Python process does not exit on GTK loop exit


problem

I am loosely following this Python GTK tutorial, but the Python process itself does not exit after the gtk main loop is exited, and does not respond to a terminal interrupt either--it has to be killed (SIGTERM). Here is my complete code:

from gi.repository import Gtk
from sys import exit

# debugger
# import pdb; pdb.set_trace()

class Handler:
    def on_MainWindow_destroy(self):
        Gtk.main_quit(*args)
        exit()

if __name__ == '__main__':
    builder = Gtk.Builder()
    builder.add_from_file('gtkgui.glade')
    builder.connect_signals(Handler())

    window = builder.get_object("window1")
    window.show_all()

    Gtk.main()

I ran the script with a glade interface, and it appears okay, interacts visually, and closes on exit, but the python process stays running and does not let go of the terminal. (I am running Ubuntu 12.10 at the moment.)

[21時25分47秒]▶ python --version
Python 2.7.3
[21時25分47秒]▶ python clientest.py 

(window appears, close window)
^C^C^C^C^C^C
(no response)

what I tried

I added quit() and exit() separately following suggestions from this question with no change in behavior.

I also tried debugging following the instructions from this question, but the debugger also seems to hang along with the script at the end.

question

Is this expected behavior? How to ensure the Python process quits when the GTK loop is ended?


Solution

  • In PyGObject, Gtk.main_quit accepts a variable number of arguments (which are ignored). This means you can use it directly as a callback connected to the "destroy" signal of a window.

    window.connect('destroy', Gtk.main_quit)
    

    You should also be able to connect this from the glade file by setting up a "destroy" signal handler in Glade similar to what you've done:

    class Handler:
        def on_mainWindow_destroy(self, *args):
            Gtk.main_quit()
    
    builder.connect_signals(Handler())
    

    Note that calling sys.exit() is not needed. sys.exit() raises a "SystemExit" exception which will not pass through GTK+ signal callbacks.