23

So just like the question says, I'm trying to let keyboard interrupts happens while Gtk.main() is in progress, however, it just doesn't seem to notice that the keyboard interrupt happens until after the function is done.

So I tried sticking Gtk.main() in a separate thread, and have the main thread find the keyboard interupts, and terminate the thread, but then found out that Gtk doesn't play nicely with threads as described in this article

I can't think of any other way to let keyboard interrupts work. Is this possible?

I'm using python3, and want my program to eventually be cross platform.

QxQ
  • 675
  • 7
  • 18
  • could you clarify what it is that you want to achieve? do you want to catch things like `Ctrl + C`? – ebassi May 07 '13 at 20:58
  • exactly. if you run the program in the terminal, then push ctrl+c, nothing happens until after the window is closed – QxQ May 08 '13 at 00:40

3 Answers3

41

because of https://bugzilla.gnome.org/show_bug.cgi?id=622084 gtk applications written using pygobject will not close themselves when using Ctrl + C on the terminal.

to work around it, you can install a Unix signal handler like this:

if __name__ == '__main__':
    import signal
    signal.signal(signal.SIGINT, signal.SIG_DFL)
    your_application_main()
vahid abdi
  • 9,636
  • 4
  • 29
  • 35
ebassi
  • 8,648
  • 27
  • 29
  • This appears to work for libgit2 (pygit2) calls as well, allowing UserInterrupt to interrupt the low level library call as well (well I don't know the full details, all I know is i get my shell back immediatly) – ThorSummoner Aug 30 '18 at 18:43
10

The accepted answer would not work for me. I resolved it by replacing the Gtk.main() call with GLib.MainLoop().run(), as explained in the bug report.

sleblanc
  • 3,821
  • 1
  • 34
  • 42
4

I also ran into trouble when using the signal module to override the SIGINT handler (100% CPU on the python thread); an alternative for me was the following:

def main():
    self.mainloop = GObject.MainLoop()
    try:
        self.mainloop.run()
    except KeyboardInterrupt:
        logger.info('Ctrl+C hit, quitting')
        self.exit()

def exit():
    self.mainloop.quit()
Florent Thiery
  • 299
  • 1
  • 10