##// END OF EJS Templates
inputhookqt4: polish the qt4 related hooks...
Christian Boos -
Show More
@@ -1,91 +1,111 b''
1 1 # -*- coding: utf-8 -*-
2 2 """
3 3 Qt4's inputhook support function
4 4
5 5 Author: Christian Boos
6 6 """
7 7
8 8 #-----------------------------------------------------------------------------
9 9 # Copyright (C) 2011 The IPython Development Team
10 10 #
11 11 # Distributed under the terms of the BSD License. The full license is in
12 12 # the file COPYING, distributed as part of this software.
13 13 #-----------------------------------------------------------------------------
14 14
15 15 #-----------------------------------------------------------------------------
16 16 # Imports
17 17 #-----------------------------------------------------------------------------
18 18
19 19 from IPython.core import ipapi
20 20 from IPython.external.qt_for_kernel import QtCore, QtGui
21 21 from IPython.lib.inputhook import stdin_ready
22 22
23 23 #-----------------------------------------------------------------------------
24 24 # Code
25 25 #-----------------------------------------------------------------------------
26 26
27 27 def create_inputhook_qt4(mgr, app=None):
28 28 """Create an input hook for running the Qt4 application event loop.
29 29
30 30 Parameters
31 31 ----------
32 32 mgr : an InputHookManager
33 33
34 34 app : Qt Application, optional.
35 35 Running application to use. If not given, we probe Qt for an
36 36 existing application object, and create a new one if none is found.
37 37
38 38 Returns
39 39 -------
40 40 A pair consisting of a Qt Application (either the one given or the
41 41 one found or created) and a inputhook.
42 42
43 43 Notes
44 44 -----
45 We use a custom input hook instead of PyQt4's default one, as it
46 interacts better with the readline packages (issue #481).
47
45 48 The inputhook function works in tandem with a 'pre_prompt_hook'
46 49 which automatically restores the hook as an inputhook in case the
47 50 latter has been temporarily disabled after having intercepted a
48 51 KeyboardInterrupt.
49 52 """
53
50 54 if app is None:
51 55 app = QtCore.QCoreApplication.instance()
52 56 if app is None:
53 57 app = QtGui.QApplication([" "])
54 58
55 # Always use a custom input hook instead of PyQt4's default
56 # one, as it interacts better with readline packages (issue
57 # #481).
59 # Re-use previously created inputhook if any
60 ip = ipapi.get()
61 if hasattr(ip, '_inputhook_qt4'):
62 return app, ip._inputhook_qt4
58 63
59 # Note that we can't let KeyboardInterrupt escape from that
60 # hook, as no exception can be raised from within a ctypes
61 # python callback. We need to make a compromise: a trapped
62 # KeyboardInterrupt will temporarily disable the input hook
63 # until we start over with a new prompt line with a second
64 # CTRL+C.
64 # Otherwise create the inputhook_qt4/preprompthook_qt4 pair of
65 # hooks (they both share the got_kbdint flag)
65 66
66 67 got_kbdint = [False]
67 68
68 69 def inputhook_qt4():
70 """PyOS_InputHook python hook for Qt4.
71
72 Process pending Qt events and if there's no pending keyboard
73 input, spend a short slice of time (50ms) running the Qt event
74 loop.
75
76 As a Python ctypes callback can't raise an exception, we catch
77 the KeyboardInterrupt and temporarily deactivate the hook,
78 which will let a *second* CTRL+C be processed normally and go
79 back to a clean prompt line.
80 """
69 81 try:
82 app = QtCore.QCoreApplication.instance()
70 83 app.processEvents(QtCore.QEventLoop.AllEvents, 300)
71 84 if not stdin_ready():
72 85 timer = QtCore.QTimer()
73 86 timer.timeout.connect(app.quit)
74 87 while not stdin_ready():
75 88 timer.start(50)
76 89 app.exec_()
77 90 timer.stop()
78 91 except KeyboardInterrupt:
79 92 got_kbdint[0] = True
80 93 mgr.clear_inputhook()
81 94 print("\n(event loop interrupted - "
82 95 "hit CTRL+C again to clear the prompt)")
83 96 return 0
84 97
85 98 def preprompthook_qt4(ishell):
99 """'pre_prompt_hook' used to restore the Qt4 input hook
100
101 (in case the latter was temporarily deactivated after a
102 CTRL+C)
103 """
86 104 if got_kbdint[0]:
87 105 mgr.set_inputhook(inputhook_qt4)
88 106 got_kbdint[0] = False
89 ipapi.get().set_hook('pre_prompt_hook', preprompthook_qt4)
107
108 ip._inputhook_qt4 = inputhook_qt4
109 ip.set_hook('pre_prompt_hook', preprompthook_qt4)
90 110
91 111 return app, inputhook_qt4
General Comments 0
You need to be logged in to leave comments. Login now