I have a PyQt program that is displaying some widgets and buttons.
I want the program to run either as a standalone python instance, or inside an ipython environment. I
Actually, the dev's answer pointed me in the right direction: the problem is that each time an ipython cell is executed, a new sys.excepthook is monkeypatched, once the execution is done, the sys.excepthook is brought back to the previous one (see ipkernel/kernelapp.py).
Because of this, changing sys.excepthook in a normal ipython cell instruction will not change the excepthook that is executed during the qt event loop.
A simple solution is to monkeypatch sys.excepthook inside a qt event:
from PyQt4 import QtCore, QtGui
import sys
from traceback import format_exception
def new_except_hook(etype, evalue, tb):
QtGui.QMessageBox.information(None,
str('error'),
''.join(format_exception(etype, evalue, tb)))
def patch_excepthook():
sys.excepthook = new_except_hook
TIMER = QtCore.QTimer()
TIMER.setSingleShot(True)
TIMER.timeout.connect(patch_excepthook)
TIMER.start()
A nice thing about this method is that it works for standalone and ipython execution alike.
I guess one could also imagine to monkey patch a different version of new_except_hook depending on what widget is triggering the exception by calling patch_excepthook inside the event_handler of each widget.