Ending the GTK+ main loop in an Python MDI application
Question: I am trying to code an application that consists of various windows (e.g.,
generic message dialog, login dialog, main interface, etc.) and am having
trouble getting the `gtk.main_quit` function to be called: either I get a
complaint about the call being outside the main loop, or the function doesn't
get called at all.

I am a newbie to both Python and GTK+, but my best guess as to how to get this
to work is to have a "root" window, which is just a placeholder that is never
seen, but controls the application's GTK+ loop. My code, so far, is as
follows:

    
    
    import pygtk
    pygtk.require("2.0")
    import gtk
    
    class App(gtk.Window):
      _exitStatus = 0
    
      # Generic message box
      def msg(self, title, text, type = gtk.MESSAGE_INFO, buttons = gtk.BUTTONS_OK):
        # Must always have a button
        if buttons == gtk.BUTTONS_NONE:
          buttons = gtk.BUTTONS_OK
    
        dialog = gtk.MessageDialog(None, 0, type, buttons, title)
        dialog.set_title(title)
        dialog.set_geometry_hints(min_width = 300)
        dialog.set_resizable(False)
        dialog.set_deletable(False)
        dialog.set_position(gtk.WIN_POS_CENTER)
        dialog.set_modal(True)
        dialog.format_secondary_text(text)
    
        response = dialog.run()
        dialog.destroy()
    
        return response
    
      def nuke(self, widget, data):
        gtk.main_quit()
        exit(self._exitStatus)
    
      def __init__(self):
        super(App, self).__init__()
        self.connect('destroy', self.nuke)
    
        try:
          raise Exception()
        except:
          self.msg('OMFG!', 'WTF just happened!?', gtk.MESSAGE_ERROR, gtk.BUTTONS_CLOSE)
          self._exitStatus = 1
          self.destroy()
    
        if self.msg('OK', 'Everything worked fine') == gtk.RESPONSE_OK:
          self.destroy()
    
    # Let's go!
    App()
    gtk.main()
    

The `nuke` function never gets called, despite the explicit calls to
`destroy`.

* * *

**DIFF** On @DonQuestion's advice:

    
    
    - self.destroy()
    + self.emit('destroy')
    
    - App()
    + app = App()
    

This didn't solve the problem...

* * *

**UPDATE** Accepted @jku's answer, but also see my own answer for extra
information...


Answer: First, there is a bit of a test problem with the code: You call
Gtk.main_quit() from the App initialization: this happens before main loop is
even running so signals probably won't work.

Second, you'll probably get a warning on destroy(): 'destroy' handler only
takes two arguments (self plus one) but yours has three...

Also with regards to your comment about control flow: You don't need a Window
to get signals as they're a GObject feature. And for your testing needs you
could write a App.test_except() function and use `glib.idle_add
(self.test_except)` in the object initialization -- this way test_except() is
called when main loop is running.

