Comment 1 for bug 974740

This is a tricky one. We are unable to catch the KeyboardInterrupt from, as it gets lost in the Gtk's separate thread. We might use a signal handler for SIGINT, and use it to hide and destroy the window, but it will not work, as hiding/destroying widgets requires a Gtk iteration, which we'll be unable to trigger due to the order of how Python's "pending calls" will be proceeded, and at the time we execute the signal handler, the GUI will have already received a KeyboardInterrupt, which causes it to stop working.

The best way I've found it to add
    signal.signal(signal.SIGINT, signal.SIG_DFL)
to main(), it instructs the app to call the default signal handler, when it gets the SIGINT.
This actually closes the window and stops the program completely. However, this will not prevent the Gtk thread from complaining about handled KeyboardInterrupt in the standard output, because that thread will receive the interrupt first. All in all, that's not a minor problem, just an ugly traceback when pressing Ctrl+C.

I've linked in a branch that demonstrates this solution.