Search code examples
pythonuser-interfacepygtkglade

Destroyed about dialog doesn't reappear properly


I'm working on a GUI application in Python / Glade, and have the following issue. I am trying to get an About dialog properly working...however when I click 'Close' (in the About dialog) and then attempt to open it again, this is all I see:

enter image description here

So, just a tiny little snippet of the window, and a non-functioning close button. This is my class for my Glade window:

# glade object
class MainWindow(object):
  builder_ = None

  # load main window
  def __init__(self):
    handler = {
      "sigWindowDestroy" : gtk.main_quit,
      "sigShowAbout"     : self.show_about
    }

    projfile = "proj.glade"
    self.builder_ = gtk.Builder()
    self.builder_.add_from_file(projfile)
    self.builder_.connect_signals(handler)
    window = self.builder_.get_object("main_window")
    window.show()

  # show about dialog
  def show_about(self, *args):
    dAbout = self.builder_.get_object("dAbout")
    dAbout.run()
    dAbout.destroy()

And in my main function:

  # load glade gui
  app = MainWindow()
  gtk.main()

On the second click, I see the following output in my terminal window (using Mac OS X).

GtkWarning: gtk_widget_show: assertion `GTK_IS_WIDGET (widget)' failed
  dAbout.run()
GtkWarning: gtk_label_set_markup: assertion `GTK_IS_LABEL (label)' failed
  dAbout.run()

Edit: sorry, must reopen for general unfamiliarity with PyGTK.

I've used the show()/hide() methods instead of run()/destroy() as proposed. Now, I was following along with another SO post, which highlighted this tutorial (who said to use run()/destroy()), and am seeing this behavior.

First, the Close button does nothing. I had thought for some reason its behavior was pre-defined. Second, closing the dialog with the corner close button still provides the same behavior that I see with run()/destroy() as above.


Edit 2: Solved by adding the following:

dAbout.connect("response", lambda d, r: d.hide())

Solution

  • Don't try to (deep-)copy a widget. It doesn't work, as you found out.

    Instead, hide() the dialog instead of destroy()ing it.