[PyKDE] PyQt4 & KeyboardInterrupt

Giovanni Bajo rasky at develer.com
Fri Dec 22 15:34:33 GMT 2006


Kelly Burkhart wrote:

> How do I enable proper KeyboardInterrupt handling from within a PyQt4
> application?  Is there some way I can prevent PyQt from intercepting
> SIGINT?
>
> import signal
> ...
> signal.signal(signal.SIGINT, signal.SIG_DFL)
>
> Is an improvement, but I would prefer that SIGINT triggers a
> KeyboardInterrupt exception.

The problem is that there is no way to make the Python exception
automatically propagate through the C++ Qt code. Remeber that the call stack
is something like this:

main Python script ->
qApp.exec_() ->
QApplication::exec() ->
C++ event loop ->
Event dispatching ->
C++ code for handling slots/events ->
Python code for handling slots/events.

So, basically you have Python -> C++ -> Python, where 99% of your Python
code is the inner one. When an exception is raised there, it can unwind the
stack and propagate up to the C++ layer, but it's then swallowed and the
application event loop continues.

What I usually do is to install a custom Python except hook
(sys.except_hook). That function will be called every time a Python
exception is unhandled and unwind up to the C++ layer. In the except hook, I
format the traceback into a QMessageBox, display it to the user (and print
it to the console too of course), and when the user presses OK, I call
qApp.quit(). This makes the C++ event loop abort and the application exits.

This is meant for developers of course: when shipping the application, the
traceback is better logged into a logfile, and the messagebox should display
something like "internal error, please send bug report" :)
-- 
Giovanni Bajo




More information about the PyQt mailing list