The way ipython seem to integrate with qt eventloop is by registering a callback that gets executed periodically when Python is waiting for input.  The callback runs the qt eventloop for 50 ms so all the mouse/windowing stuff gets handled.  The problem is you can't raise exceptions in this callback, so CTRL-C won't work at all.

The original author got around this by catching the SIGINT, and the disabling the callback (which means the next CTRL-C will be caught by python proper and not the callback).

I tried to get around that by making it send a ctrl-c to itself after the first ctrl-c, but this SIGINT has to arrive after it exits the inputhook callback, hence the need for threads/timers.