Skip to content

Commit

Permalink
inputhook: make PyQt4 plays nicer with pyreadline
Browse files Browse the repository at this point in the history
PyQt4's own input hook is not really appropriate when PyReadline is active
(and possibly other readline packages running the PyOS_InputHook repeatedly).
Arguably this should be fixed in PyQt4 itself, but in the meantime we can
install a local hook which does the Qt event loop processing in a less
aggressive way.
  • Loading branch information
cboos committed Oct 9, 2011
1 parent a761793 commit 76f9a74
Showing 1 changed file with 21 additions and 21 deletions.
42 changes: 21 additions & 21 deletions IPython/lib/inputhook.py
Expand Up @@ -197,31 +197,31 @@ def enable_qt4(self, app=None):
"""
from IPython.external.qt_for_kernel import QtCore, QtGui

if 'pyreadline' in sys.modules:
# see IPython GitHub Issue #281 for more info on this issue
# Similar intermittent behavior has been reported on OSX,
# but not consistently reproducible
warnings.warn("""PyReadline's inputhook can conflict with Qt, causing delays
in interactive input. If you do see this issue, we recommend using another GUI
toolkit if you can, or disable readline with the configuration option
'TerminalInteractiveShell.readline_use=False', specified in a config file or
at the command-line""",
RuntimeWarning)

# PyQt4 has had this since 4.3.1. In version 4.2, PyOS_InputHook
# was set when QtCore was imported, but if it ever got removed,
# you couldn't reset it. For earlier versions we can
# probably implement a ctypes version.
try:
QtCore.pyqtRestoreInputHook()
except AttributeError:
pass

self._current_gui = GUI_QT4
if app is None:
app = QtCore.QCoreApplication.instance()
if app is None:
app = QtGui.QApplication([" "])

# Always use the following input hook instead of PyQt4's
# default one, as it interacts better with readline packages
# (issue #481)

def inputhook_qt4():
try:
app.processEvents(QtCore.QEventLoop.AllEvents, 300)
if not stdin_ready():
timer = QtCore.QTimer()
timer.timeout.connect(app.quit)
while not stdin_ready():
timer.start(50)
app.exec_()
timer.stop()
except KeyboardInterrupt:
pass
return 0
self.set_inputhook(inputhook_qt4)

self._current_gui = GUI_QT4
app._in_event_loop = True
self._apps[GUI_QT4] = app
return app
Expand Down

0 comments on commit 76f9a74

Please sign in to comment.