[IPython-dev] replacement for appstart_qt4(app) ?
Martin Spacek
ipython at mspacek.mm.st
Fri May 20 16:58:57 EDT 2011
Motivated by ipython-qtconsole, I've taken the plunge and switched from 0.10 to
git master. Apologies if this post is more appropriate for ipython-user.
I have an app that used appstart_qt4(app) in its __name__ == '__main__' block to
automatically drop into the IPython debugger on any error. This is still
referenced in:
docs/examples/lib/gui-qt.py
appstart_qt4() is now gone from git master, and I can't seem to find any mention
of what to use in its place. get_app_qt4() and start_event_loop_qt4() in
IPython.lib.guisupport seem like good candidates, but AFAICT they don't
automatically drop you into the ipdb on an error.
I did however find this sys.excepthook method, which seems to work:
http://ipython.scipy.org/doc/manual/html/interactive/reference.html#automatic-invocation-of-pdb-on-exceptions
I want to both allow the user to drop into ipython at any point in time, as well
as automatically drop into it on any error. After some messing around, I put
together this minimal working example for git master:
import sys
from PyQt4 import QtCore, QtGui
from IPython import embed
from IPython.core import ultratb
def set_excepthook():
"""Drops us into IPython's debugger on any error"""
sys.excepthook = ultratb.FormattedTB(mode='Verbose', call_pdb=1)
class SimpleWindow(QtGui.QWidget):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.setGeometry(300, 300, 300, 200)
self.setWindowTitle('embed and ipdb test')
shellButton = QtGui.QPushButton('drop into shell', self)
shellButton.setGeometry(10, 10, 100, 35)
self.connect(shellButton, QtCore.SIGNAL('clicked()'),
self.shell)
raiseErrorButton = QtGui.QPushButton('raise Error', self)
raiseErrorButton.setGeometry(10, 50, 100, 35)
self.connect(raiseErrorButton, QtCore.SIGNAL('clicked()'),
self.raise_error)
def shell(self):
embed(display_banner=False) # "self" is accessible from the shell
# embed() seems to override the excepthook, need to reset it:
set_excepthook()
def raise_error(self):
raise RuntimeError
if __name__ == "__main__":
# prevents "The event loop is already running" errors:
QtCore.pyqtRemoveInputHook()
set_excepthook()
app = QtGui.QApplication(sys.argv)
window = SimpleWindow()
window.show()
sys.exit(app.exec_())
Hitting the shell button drops you into ipython, and hitting the raise Error
button drops you into ipdb to inspect the error. I've noticed the embed() call
clears the sys.excepthook setting, so I have to constantly reset it afterwards.
Seems a bit messy. Is there a better way to do this?
What I'd ultimately want is a second Qt window running ipython-qtconsole in
tandem with the main window, so the user never has to hit the "shell" button to
stop the Qt loop just to inspect all of the existing objects. I used to have
this kind of functionality in wxPython with pycrust/pyshell. Is such a thing
currently possible with IPython in Qt?
Cheers,
Martin
More information about the IPython-dev
mailing list