From 76f9a74750ecfe0325aa2d3213b8720b7c584936 2011-10-09 12:12:01 From: Christian Boos Date: 2011-10-09 12:12:01 Subject: [PATCH] inputhook: make PyQt4 plays nicer with pyreadline 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. --- diff --git a/IPython/lib/inputhook.py b/IPython/lib/inputhook.py index 655c1d0..ee16beb 100644 --- a/IPython/lib/inputhook.py +++ b/IPython/lib/inputhook.py @@ -197,31 +197,31 @@ class InputHookManager(object): """ 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