Search code examples
pythonuser-interfacegtkgtk3pygobject

Gtk Dialogs appear only once


I am writing a GUI app with python and GTK (PyGobject). Here is my application class:

class Application(Gtk.Application):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, application_id='org.tractor.carburetor', **kwargs)
        self.window = None
        self.prefs = None
        self.about = None

    def do_startup(self):
        Gtk.Application.do_startup(self)

        action = Gio.SimpleAction.new('preferences', None)
        action.connect('activate', self.on_preferences)
        self.add_action(action)

        action = Gio.SimpleAction.new('about', None)
        action.connect('activate', self.on_about)
        self.add_action(action)

        action = Gio.SimpleAction.new("quit", None)
        action.connect('activate', self.on_quit)
        self.add_action(action)

    def do_activate(self):
        if not self.window:
            window = AppWindow(application=self) #GtkApplicationWindow
            self.window = window
        self.window.present()

    def on_preferences(self, action, param):
        if not self.prefs:
            prefs_window = ui.get('PreferencesWindow') #HdyPreferencesWindow
            prefs_window.set_transient_for(self.window)
            self.prefs = prefs_window
        self.prefs.show()

    def on_about(self, action, param):
        if not self.about:
            about_dialog = ui.get('AboutDialog') #GtkAboutDialog
            about_dialog.set_transient_for(self.window)
            self.about = about_dialog
        self.about.show()

    def on_quit(self, action, param):
        self.quit()

When I click on preferences or about in app menu, every thing is fine. But after closing the dialogs, if I click them again, I get errors and an empty window will appear.

Here are the errors:

(carburetor:157852): Gtk-CRITICAL **: 19:41:29.887: gtk_widget_show: assertion
'GTK_IS_WIDGET (widget)' failed
(carburetor:157852): Gtk-CRITICAL **: 19:41:29.887: gtk_label_set_markup:
assertion 'GTK_IS_LABEL (label)' failed

Solution

  • You need to override what happens when they are closed so that they aren't destroyed and instead simply hide them. You can do this by adding an event handler to the dialogs for the destroy event and in that just do dialog_window.hide() so that you can redisplay them by using present. Also don't forget to return the right boolean to suppress further event propagation.