Show More
@@ -22,6 +22,9 b' import sys' | |||||
22 | # Code |
|
22 | # Code | |
23 | #----------------------------------------------------------------------------- |
|
23 | #----------------------------------------------------------------------------- | |
24 |
|
24 | |||
|
25 | def _dummy_mainloop(*args, **kw): | |||
|
26 | pass | |||
|
27 | ||||
25 |
|
28 | |||
26 | class InputHookManager(object): |
|
29 | class InputHookManager(object): | |
27 | """Manage PyOS_InputHook for different GUI toolkits. |
|
30 | """Manage PyOS_InputHook for different GUI toolkits. | |
@@ -32,6 +35,7 b' class InputHookManager(object):' | |||||
32 |
|
35 | |||
33 | def __init__(self): |
|
36 | def __init__(self): | |
34 | self.PYFUNC = ctypes.PYFUNCTYPE(ctypes.c_int) |
|
37 | self.PYFUNC = ctypes.PYFUNCTYPE(ctypes.c_int) | |
|
38 | self._apps = {} | |||
35 | self._reset() |
|
39 | self._reset() | |
36 |
|
40 | |||
37 | def _reset(self): |
|
41 | def _reset(self): | |
@@ -40,6 +44,35 b' class InputHookManager(object):' | |||||
40 | self._installed = False |
|
44 | self._installed = False | |
41 | self._current_gui = None |
|
45 | self._current_gui = None | |
42 |
|
46 | |||
|
47 | def _hijack_wx(self): | |||
|
48 | import wx | |||
|
49 | if hasattr(wx, '_core_'): core = getattr(wx, '_core_') | |||
|
50 | elif hasattr(wx, '_core'): core = getattr(wx, '_core') | |||
|
51 | else: raise AttributeError('Could not find wx core module') | |||
|
52 | orig_mainloop = core.PyApp_MainLoop | |||
|
53 | core.PyApp_MainLoop = _dummy_mainloop | |||
|
54 | return orig_mainloop | |||
|
55 | ||||
|
56 | def _hijack_qt4(self): | |||
|
57 | from PyQt4 import QtGui, QtCore | |||
|
58 | orig_mainloop = QtGui.qApp.exec_ | |||
|
59 | QtGui.qApp.exec_ = _dummy_mainloop | |||
|
60 | QtGui.QApplication.exec_ = _dummy_mainloop | |||
|
61 | QtCore.QCoreApplication.exec_ = _dummy_mainloop | |||
|
62 | return orig_mainloop | |||
|
63 | ||||
|
64 | def _hijack_gtk(self): | |||
|
65 | import gtk | |||
|
66 | orig_mainloop = gtk.main | |||
|
67 | gtk.mainloop = _dummy_mainloop | |||
|
68 | gtk.main = _dummy_mainloop | |||
|
69 | return orig_mainloop | |||
|
70 | ||||
|
71 | def _hijack_tk(self): | |||
|
72 | import Tkinter | |||
|
73 | Tkinter.Misc.mainloop = _dummy_mainloop | |||
|
74 | Tkinter.mainloop = _dummy_mainloop | |||
|
75 | ||||
43 | def get_pyos_inputhook(self): |
|
76 | def get_pyos_inputhook(self): | |
44 | """Return the current PyOS_InputHook as a ctypes.c_void_p. |
|
77 | """Return the current PyOS_InputHook as a ctypes.c_void_p. | |
45 | """ |
|
78 | """ | |
@@ -71,6 +104,21 b' class InputHookManager(object):' | |||||
71 | self._reset() |
|
104 | self._reset() | |
72 | return original |
|
105 | return original | |
73 |
|
106 | |||
|
107 | def clear_app_refs(self, gui=None): | |||
|
108 | """Clear IPython's internal reference to an application instance. | |||
|
109 | ||||
|
110 | Parameters | |||
|
111 | ---------- | |||
|
112 | gui : None or str | |||
|
113 | If None, clear all app references. If ('wx', 'qt4') clear | |||
|
114 | the app for that toolkit. References are not held for gtk or tk | |||
|
115 | as those toolkits don't have the notion of an app. | |||
|
116 | """ | |||
|
117 | if gui is None: | |||
|
118 | self._apps = {} | |||
|
119 | elif self._apps.has_key(gui): | |||
|
120 | del self._apps[gui] | |||
|
121 | ||||
74 | def enable_wx(self, app=False): |
|
122 | def enable_wx(self, app=False): | |
75 | """Enable event loop integration with wxPython. |
|
123 | """Enable event loop integration with wxPython. | |
76 |
|
124 | |||
@@ -99,15 +147,13 b' class InputHookManager(object):' | |||||
99 | from IPython.lib.inputhookwx import inputhook_wx |
|
147 | from IPython.lib.inputhookwx import inputhook_wx | |
100 | self.set_inputhook(inputhook_wx) |
|
148 | self.set_inputhook(inputhook_wx) | |
101 | self._current_gui = 'wx' |
|
149 | self._current_gui = 'wx' | |
|
150 | self._hijack_wx() | |||
102 | if app: |
|
151 | if app: | |
103 | import wx |
|
152 | import wx | |
104 | app = wx.App(redirect=False, clearSigInt=False) |
|
153 | app = wx.GetApp() | |
105 | # The import of wx on Linux sets the handler for signal.SIGINT |
|
154 | if app is None: | |
106 | # to 0. This is a bug in wx or gtk. We fix by just setting it |
|
155 | app = wx.App(redirect=False, clearSigInt=False) | |
107 | # back to the Python default. |
|
156 | self._apps['wx'] = app | |
108 | import signal |
|
|||
109 | if not callable(signal.getsignal(signal.SIGINT)): |
|
|||
110 | signal.signal(signal.SIGINT, signal.default_int_handler) |
|
|||
111 | return app |
|
157 | return app | |
112 |
|
158 | |||
113 | def disable_wx(self): |
|
159 | def disable_wx(self): | |
@@ -145,9 +191,13 b' class InputHookManager(object):' | |||||
145 | except AttributeError: |
|
191 | except AttributeError: | |
146 | pass |
|
192 | pass | |
147 | self._current_gui = 'qt4' |
|
193 | self._current_gui = 'qt4' | |
|
194 | self._hijack_qt4() | |||
148 | if app: |
|
195 | if app: | |
149 | from PyQt4 import QtGui |
|
196 | from PyQt4 import QtGui | |
150 |
app = QtGui.QApplication( |
|
197 | app = QtGui.QApplication.instance() | |
|
198 | if app is None: | |||
|
199 | app = QtGui.QApplication(sys.argv) | |||
|
200 | self._apps['qt4'] = app | |||
151 | return app |
|
201 | return app | |
152 |
|
202 | |||
153 | def disable_qt4(self): |
|
203 | def disable_qt4(self): | |
@@ -184,6 +234,7 b' class InputHookManager(object):' | |||||
184 | from IPython.lib.inputhookgtk import inputhook_gtk |
|
234 | from IPython.lib.inputhookgtk import inputhook_gtk | |
185 | self.set_inputhook(inputhook_gtk) |
|
235 | self.set_inputhook(inputhook_gtk) | |
186 | self._current_gui = 'gtk' |
|
236 | self._current_gui = 'gtk' | |
|
237 | self._hijack_gtk() | |||
187 |
|
238 | |||
188 | def disable_gtk(self): |
|
239 | def disable_gtk(self): | |
189 | """Disable event loop integration with PyGTK. |
|
240 | """Disable event loop integration with PyGTK. | |
@@ -206,6 +257,7 b' class InputHookManager(object):' | |||||
206 | sets ``PyOS_InputHook``. |
|
257 | sets ``PyOS_InputHook``. | |
207 | """ |
|
258 | """ | |
208 | self._current_gui = 'tk' |
|
259 | self._current_gui = 'tk' | |
|
260 | self._hijack_tk() | |||
209 |
|
261 | |||
210 | def disable_tk(self): |
|
262 | def disable_tk(self): | |
211 | """Disable event loop integration with Tkinter. |
|
263 | """Disable event loop integration with Tkinter. | |
@@ -230,4 +282,5 b' enable_tk = inputhook_manager.enable_tk' | |||||
230 | disable_tk = inputhook_manager.disable_tk |
|
282 | disable_tk = inputhook_manager.disable_tk | |
231 | clear_inputhook = inputhook_manager.clear_inputhook |
|
283 | clear_inputhook = inputhook_manager.clear_inputhook | |
232 | set_inputhook = inputhook_manager.set_inputhook |
|
284 | set_inputhook = inputhook_manager.set_inputhook | |
233 | current_gui = inputhook_manager.current_gui No newline at end of file |
|
285 | current_gui = inputhook_manager.current_gui | |
|
286 | clear_app_refs = inputhook_manager.clear_app_refs |
@@ -19,6 +19,7 b' Authors: Robin Dunn, Brian Granger, Ondrej Certik' | |||||
19 | #----------------------------------------------------------------------------- |
|
19 | #----------------------------------------------------------------------------- | |
20 |
|
20 | |||
21 | import os |
|
21 | import os | |
|
22 | import signal | |||
22 | import sys |
|
23 | import sys | |
23 | import time |
|
24 | import time | |
24 | from timeit import default_timer as clock |
|
25 | from timeit import default_timer as clock | |
@@ -122,6 +123,12 b' def inputhook_wx3():' | |||||
122 | if app is not None: |
|
123 | if app is not None: | |
123 | assert wx.Thread_IsMain() |
|
124 | assert wx.Thread_IsMain() | |
124 |
|
125 | |||
|
126 | # The import of wx on Linux sets the handler for signal.SIGINT | |||
|
127 | # to 0. This is a bug in wx or gtk. We fix by just setting it | |||
|
128 | # back to the Python default. | |||
|
129 | if not callable(signal.getsignal(signal.SIGINT)): | |||
|
130 | signal.signal(signal.SIGINT, signal.default_int_handler) | |||
|
131 | ||||
125 | evtloop = wx.EventLoop() |
|
132 | evtloop = wx.EventLoop() | |
126 | ea = wx.EventLoopActivator(evtloop) |
|
133 | ea = wx.EventLoopActivator(evtloop) | |
127 | t = clock() |
|
134 | t = clock() | |
@@ -139,7 +146,9 b' def inputhook_wx3():' | |||||
139 | # 0.001 13% |
|
146 | # 0.001 13% | |
140 | # 0.005 3% |
|
147 | # 0.005 3% | |
141 | # 0.01 1.5% |
|
148 | # 0.01 1.5% | |
142 |
# 0.05 0.5% |
|
149 | # 0.05 0.5% | |
|
150 | if clock()-t > 1.0: | |||
|
151 | time.sleep(1.0) | |||
143 | if clock()-t > 0.1: |
|
152 | if clock()-t > 0.1: | |
144 | # Few GUI events coming in, so we can sleep longer |
|
153 | # Few GUI events coming in, so we can sleep longer | |
145 | time.sleep(0.05) |
|
154 | time.sleep(0.05) |
General Comments 0
You need to be logged in to leave comments.
Login now