Show More
@@ -0,0 +1,90 b'' | |||||
|
1 | # -*- coding: utf-8 -*- | |||
|
2 | """ | |||
|
3 | Qt4's inputhook support function | |||
|
4 | ||||
|
5 | Author: Christian Boos | |||
|
6 | """ | |||
|
7 | ||||
|
8 | #----------------------------------------------------------------------------- | |||
|
9 | # Copyright (C) 2011 The IPython Development Team | |||
|
10 | # | |||
|
11 | # Distributed under the terms of the BSD License. The full license is in | |||
|
12 | # the file COPYING, distributed as part of this software. | |||
|
13 | #----------------------------------------------------------------------------- | |||
|
14 | ||||
|
15 | #----------------------------------------------------------------------------- | |||
|
16 | # Imports | |||
|
17 | #----------------------------------------------------------------------------- | |||
|
18 | ||||
|
19 | from IPython.core import ipapi | |||
|
20 | from IPython.external.qt_for_kernel import QtCore, QtGui | |||
|
21 | from IPython.lib.inputhook import stdin_ready | |||
|
22 | ||||
|
23 | #----------------------------------------------------------------------------- | |||
|
24 | # Code | |||
|
25 | #----------------------------------------------------------------------------- | |||
|
26 | ||||
|
27 | def create_inputhook_qt4(mgr, app=None): | |||
|
28 | """Create an input hook for running the Qt4 application event loop. | |||
|
29 | ||||
|
30 | Parameters | |||
|
31 | ---------- | |||
|
32 | mgr : an InputHookManager | |||
|
33 | ||||
|
34 | app : Qt Application, optional. | |||
|
35 | Running application to use. If not given, we probe Qt for an | |||
|
36 | existing application object, and create a new one if none is found. | |||
|
37 | ||||
|
38 | Returns | |||
|
39 | ------- | |||
|
40 | A pair consisting of a Qt Application (either the one given or the | |||
|
41 | one found or created) and a inputhook. | |||
|
42 | ||||
|
43 | Notes | |||
|
44 | ----- | |||
|
45 | The inputhook function works in tandem with a 'pre_prompt_hook' | |||
|
46 | which automatically restores the hook as an inputhook in case the | |||
|
47 | latter has been temporarily disabled after having intercepted a | |||
|
48 | KeyboardInterrupt. | |||
|
49 | """ | |||
|
50 | if app is None: | |||
|
51 | app = QtCore.QCoreApplication.instance() | |||
|
52 | if app is None: | |||
|
53 | app = QtGui.QApplication([" "]) | |||
|
54 | ||||
|
55 | # Always use a custom input hook instead of PyQt4's default | |||
|
56 | # one, as it interacts better with readline packages (issue | |||
|
57 | # #481). | |||
|
58 | ||||
|
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. | |||
|
65 | ||||
|
66 | got_kbdint = [False] | |||
|
67 | ||||
|
68 | def inputhook_qt4(): | |||
|
69 | try: | |||
|
70 | app.processEvents(QtCore.QEventLoop.AllEvents, 300) | |||
|
71 | if not stdin_ready(): | |||
|
72 | timer = QtCore.QTimer() | |||
|
73 | timer.timeout.connect(app.quit) | |||
|
74 | while not stdin_ready(): | |||
|
75 | timer.start(50) | |||
|
76 | app.exec_() | |||
|
77 | timer.stop() | |||
|
78 | except KeyboardInterrupt: | |||
|
79 | got_kbdint[0] = True | |||
|
80 | mgr.clear_inputhook() | |||
|
81 | print("\n(event loop interrupted - " | |||
|
82 | "hit CTRL+C again to clear the prompt)") | |||
|
83 | return 0 | |||
|
84 | ||||
|
85 | def preprompthook_qt4(ishell): | |||
|
86 | if got_kbdint[0]: | |||
|
87 | mgr.set_inputhook(inputhook_qt4) | |||
|
88 | ipapi.get().set_hook('pre_prompt_hook', preprompthook_qt4) | |||
|
89 | ||||
|
90 | return app, inputhook_qt4 |
@@ -204,49 +204,9 b' class InputHookManager(object):' | |||||
204 | from PyQt4 import QtCore |
|
204 | from PyQt4 import QtCore | |
205 | app = QtGui.QApplication(sys.argv) |
|
205 | app = QtGui.QApplication(sys.argv) | |
206 | """ |
|
206 | """ | |
207 | from IPython.external.qt_for_kernel import QtCore, QtGui |
|
207 | from IPython.lib.inputhookqt4 import create_inputhook_qt4 | |
208 | from IPython.core import ipapi |
|
208 | app, inputhook_qt4 = create_inputhook_qt4(self, app) | |
209 |
|
||||
210 | if app is None: |
|
|||
211 | app = QtCore.QCoreApplication.instance() |
|
|||
212 | if app is None: |
|
|||
213 | app = QtGui.QApplication([" "]) |
|
|||
214 |
|
||||
215 | # Always use a custom input hook instead of PyQt4's default |
|
|||
216 | # one, as it interacts better with readline packages (issue |
|
|||
217 | # #481). |
|
|||
218 |
|
||||
219 | # Note that we can't let KeyboardInterrupt escape from that |
|
|||
220 | # hook, as no exception can be raised from within a ctypes |
|
|||
221 | # python callback. We need to make a compromise: a trapped |
|
|||
222 | # KeyboardInterrupt will temporarily disable the input hook |
|
|||
223 | # until we start over with a new prompt line with a second |
|
|||
224 | # CTRL+C. |
|
|||
225 |
|
||||
226 | got_kbdint = [False] |
|
|||
227 |
|
||||
228 | def inputhook_qt4(): |
|
|||
229 | try: |
|
|||
230 | app.processEvents(QtCore.QEventLoop.AllEvents, 300) |
|
|||
231 | if not stdin_ready(): |
|
|||
232 | timer = QtCore.QTimer() |
|
|||
233 | timer.timeout.connect(app.quit) |
|
|||
234 | while not stdin_ready(): |
|
|||
235 | timer.start(50) |
|
|||
236 | app.exec_() |
|
|||
237 | timer.stop() |
|
|||
238 | except KeyboardInterrupt: |
|
|||
239 | got_kbdint[0] = True |
|
|||
240 | self.clear_inputhook() |
|
|||
241 | print("\n(event loop interrupted - " |
|
|||
242 | "hit CTRL+C again to clear the prompt)") |
|
|||
243 | return 0 |
|
|||
244 | self.set_inputhook(inputhook_qt4) |
|
|||
245 |
|
||||
246 | def preprompthook_qt4(ishell): |
|
|||
247 | if got_kbdint[0]: |
|
|||
248 |
|
|
209 | self.set_inputhook(inputhook_qt4) | |
249 | ipapi.get().set_hook('pre_prompt_hook', preprompthook_qt4) |
|
|||
250 |
|
210 | |||
251 | self._current_gui = GUI_QT4 |
|
211 | self._current_gui = GUI_QT4 | |
252 | app._in_event_loop = True |
|
212 | app._in_event_loop = True |
General Comments 0
You need to be logged in to leave comments.
Login now