Skip to content


Subversion checkout URL

You can clone with
Download ZIP
Browse files

inputhookqt4: polish the qt4 related hooks

 - make sure we don't install more than one 'pre_prompt_hook'
   for a given ipapi instance
 - clarify the internal documentation and move it from comments
   into docstrings
  • Loading branch information...
commit e3612ec5c7c5d0f68fe4b627fde8e063808f2f1b 1 parent c795b61
@cboos cboos authored
Showing with 30 additions and 10 deletions.
  1. +30 −10 IPython/lib/
40 IPython/lib/
@@ -42,31 +42,44 @@ def create_inputhook_qt4(mgr, app=None):
+ We use a custom input hook instead of PyQt4's default one, as it
+ interacts better with the readline packages (issue #481).
The inputhook function works in tandem with a 'pre_prompt_hook'
which automatically restores the hook as an inputhook in case the
latter has been temporarily disabled after having intercepted a
if app is None:
app = QtCore.QCoreApplication.instance()
if app is None:
app = QtGui.QApplication([" "])
- # Always use a custom input hook instead of PyQt4's default
- # one, as it interacts better with readline packages (issue
- # #481).
+ # Re-use previously created inputhook if any
+ ip = ipapi.get()
+ if hasattr(ip, '_inputhook_qt4'):
+ return app, ip._inputhook_qt4
- # Note that we can't let KeyboardInterrupt escape from that
- # hook, as no exception can be raised from within a ctypes
- # python callback. We need to make a compromise: a trapped
- # KeyboardInterrupt will temporarily disable the input hook
- # until we start over with a new prompt line with a second
- # CTRL+C.
+ # Otherwise create the inputhook_qt4/preprompthook_qt4 pair of
+ # hooks (they both share the got_kbdint flag)
got_kbdint = [False]
def inputhook_qt4():
+ """PyOS_InputHook python hook for Qt4.
+ Process pending Qt events and if there's no pending keyboard
+ input, spend a short slice of time (50ms) running the Qt event
+ loop.
+ As a Python ctypes callback can't raise an exception, we catch
+ the KeyboardInterrupt and temporarily deactivate the hook,
+ which will let a *second* CTRL+C be processed normally and go
+ back to a clean prompt line.
+ """
+ app = QtCore.QCoreApplication.instance()
app.processEvents(QtCore.QEventLoop.AllEvents, 300)
if not stdin_ready():
timer = QtCore.QTimer()
@@ -83,9 +96,16 @@ def inputhook_qt4():
return 0
def preprompthook_qt4(ishell):
+ """'pre_prompt_hook' used to restore the Qt4 input hook
+ (in case the latter was temporarily deactivated after a
+ """
if got_kbdint[0]:
got_kbdint[0] = False
- ipapi.get().set_hook('pre_prompt_hook', preprompthook_qt4)
+ ip._inputhook_qt4 = inputhook_qt4
+ ip.set_hook('pre_prompt_hook', preprompthook_qt4)
return app, inputhook_qt4

0 comments on commit e3612ec

Please sign in to comment.
Something went wrong with that request. Please try again.