##// END OF EJS Templates
inputhookqt4: need to ignore CTRL+C when exiting input hook
Christian Boos -
Show More
@@ -1,115 +1,116 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.external.qt_for_kernel import QtCore, QtGui
20 20 from IPython.lib.inputhook import allow_CTRL_C, ignore_CTRL_C, stdin_ready
21 21
22 22 #-----------------------------------------------------------------------------
23 23 # Code
24 24 #-----------------------------------------------------------------------------
25 25
26 26 def create_inputhook_qt4(mgr, app=None):
27 27 """Create an input hook for running the Qt4 application event loop.
28 28
29 29 Parameters
30 30 ----------
31 31 mgr : an InputHookManager
32 32
33 33 app : Qt Application, optional.
34 34 Running application to use. If not given, we probe Qt for an
35 35 existing application object, and create a new one if none is found.
36 36
37 37 Returns
38 38 -------
39 39 A pair consisting of a Qt Application (either the one given or the
40 40 one found or created) and a inputhook.
41 41
42 42 Notes
43 43 -----
44 44 We use a custom input hook instead of PyQt4's default one, as it
45 45 interacts better with the readline packages (issue #481).
46 46
47 47 The inputhook function works in tandem with a 'pre_prompt_hook'
48 48 which automatically restores the hook as an inputhook in case the
49 49 latter has been temporarily disabled after having intercepted a
50 50 KeyboardInterrupt.
51 51 """
52 52
53 53 if app is None:
54 54 app = QtCore.QCoreApplication.instance()
55 55 if app is None:
56 56 app = QtGui.QApplication([" "])
57 57
58 58 # Re-use previously created inputhook if any
59 59 ip = get_ipython()
60 60 if hasattr(ip, '_inputhook_qt4'):
61 61 return app, ip._inputhook_qt4
62 62
63 63 # Otherwise create the inputhook_qt4/preprompthook_qt4 pair of
64 64 # hooks (they both share the got_kbdint flag)
65 65
66 66 got_kbdint = [False]
67 67
68 68 def inputhook_qt4():
69 69 """PyOS_InputHook python hook for Qt4.
70 70
71 71 Process pending Qt events and if there's no pending keyboard
72 72 input, spend a short slice of time (50ms) running the Qt event
73 73 loop.
74 74
75 75 As a Python ctypes callback can't raise an exception, we catch
76 76 the KeyboardInterrupt and temporarily deactivate the hook,
77 77 which will let a *second* CTRL+C be processed normally and go
78 78 back to a clean prompt line.
79 79 """
80 80 try:
81 81 allow_CTRL_C()
82 82 app = QtCore.QCoreApplication.instance()
83 83 app.processEvents(QtCore.QEventLoop.AllEvents, 300)
84 84 if not stdin_ready():
85 85 timer = QtCore.QTimer()
86 86 timer.timeout.connect(app.quit)
87 87 while not stdin_ready():
88 88 timer.start(50)
89 89 app.exec_()
90 90 timer.stop()
91 ignore_CTRL_C()
91 92 except KeyboardInterrupt:
92 93 ignore_CTRL_C()
93 94 got_kbdint[0] = True
94 95 print("\nKeyboardInterrupt - qt4 event loop interrupted!"
95 96 "\n * hit CTRL+C again to clear the prompt"
96 97 "\n * use '%gui none' to disable the event loop"
97 98 " permanently"
98 99 "\n and '%gui qt4' to re-enable it later")
99 100 mgr.clear_inputhook()
100 101 return 0
101 102
102 103 def preprompthook_qt4(ishell):
103 104 """'pre_prompt_hook' used to restore the Qt4 input hook
104 105
105 106 (in case the latter was temporarily deactivated after a
106 107 CTRL+C)
107 108 """
108 109 if got_kbdint[0]:
109 110 mgr.set_inputhook(inputhook_qt4)
110 111 got_kbdint[0] = False
111 112
112 113 ip._inputhook_qt4 = inputhook_qt4
113 114 ip.set_hook('pre_prompt_hook', preprompthook_qt4)
114 115
115 116 return app, inputhook_qt4
General Comments 0
You need to be logged in to leave comments. Login now