简体   繁体   中英

Cannot close gtk dialog window

I am using gtk to create a file choose dialog:

from gi.repository import Gtk
import time

dialog = Gtk.FileChooserDialog("World to load:", None,
                               Gtk.FileChooserAction.OPEN,
    (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
    Gtk.STOCK_OPEN, Gtk.ResponseType.OK))

response = dialog.run()
if response == Gtk.ResponseType.OK:
    print("load", dialog.get_filename())
else:
    print("cancel")

dialog.destroy()

time.sleep(5)

The code works: I get either file name or 'cancel printed. But the chooser window does not close before the program exits 5s later. The window just hangs there the program runs further and is responsive. Replacing dialog.destroy() with dialog.hide() does not change anything as far as I can tell.

I get a warning:

Gtk-Message: 10:27:04.843: GtkDialog mapped without a transient parent. This is discouraged.

not sure if this is related.

I have tried various versions of Gtk.main() , Gtk.main_quit() and other ways to force the main loop, however, my (admittedly imperfect) reading is that file dialog implements the loops itself and does not need the main loop.

Anyone can help me to get this window to close?

I am using python 3.6.7, gi 3.26.1 on ubuntu 18.04

Here is a solution that works on my purpose. Briefly, it involves GLib timeout that closes/hides the main window, and the Gtk.main() loop that does the window cleanup. Here is the amended code:

import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, GLib
import time

def onTimeout():
    Gtk.main_quit()
    return False

win = Gtk.Window(title="test")

dialog = Gtk.FileChooserDialog("World to load:", win,
                               Gtk.FileChooserAction.OPEN,
    (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
    Gtk.STOCK_OPEN, Gtk.ResponseType.OK))
response = dialog.run()
if response == Gtk.ResponseType.OK:
    print("load", dialog.get_filename())
else:
    print("cancel")

dialog.destroy()
GLib.timeout_add(100, onTimeout)
Gtk.main()
print("window closed, wait")

time.sleep(5)

I'd be happy to learn about a cleaner solution if someone can suggest one. Forcing the main loop to do cleanup and timeout to leave it seems strange.

Simply call

dialog.show()

after

dialog.destroy()

Sounds weird, but works.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM