##// END OF EJS Templates
Work on inputhook....
Brian Granger -
Show More
@@ -22,6 +22,9 b' import sys'
22 22 # Code
23 23 #-----------------------------------------------------------------------------
24 24
25 def _dummy_mainloop(*args, **kw):
26 pass
27
25 28
26 29 class InputHookManager(object):
27 30 """Manage PyOS_InputHook for different GUI toolkits.
@@ -32,6 +35,7 b' class InputHookManager(object):'
32 35
33 36 def __init__(self):
34 37 self.PYFUNC = ctypes.PYFUNCTYPE(ctypes.c_int)
38 self._apps = {}
35 39 self._reset()
36 40
37 41 def _reset(self):
@@ -40,6 +44,35 b' class InputHookManager(object):'
40 44 self._installed = False
41 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 76 def get_pyos_inputhook(self):
44 77 """Return the current PyOS_InputHook as a ctypes.c_void_p.
45 78 """
@@ -71,6 +104,21 b' class InputHookManager(object):'
71 104 self._reset()
72 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 122 def enable_wx(self, app=False):
75 123 """Enable event loop integration with wxPython.
76 124
@@ -99,15 +147,13 b' class InputHookManager(object):'
99 147 from IPython.lib.inputhookwx import inputhook_wx
100 148 self.set_inputhook(inputhook_wx)
101 149 self._current_gui = 'wx'
150 self._hijack_wx()
102 151 if app:
103 152 import wx
153 app = wx.GetApp()
154 if app is None:
104 155 app = wx.App(redirect=False, clearSigInt=False)
105 # The import of wx on Linux sets the handler for signal.SIGINT
106 # to 0. This is a bug in wx or gtk. We fix by just setting it
107 # back to the Python default.
108 import signal
109 if not callable(signal.getsignal(signal.SIGINT)):
110 signal.signal(signal.SIGINT, signal.default_int_handler)
156 self._apps['wx'] = app
111 157 return app
112 158
113 159 def disable_wx(self):
@@ -145,9 +191,13 b' class InputHookManager(object):'
145 191 except AttributeError:
146 192 pass
147 193 self._current_gui = 'qt4'
194 self._hijack_qt4()
148 195 if app:
149 196 from PyQt4 import QtGui
197 app = QtGui.QApplication.instance()
198 if app is None:
150 199 app = QtGui.QApplication(sys.argv)
200 self._apps['qt4'] = app
151 201 return app
152 202
153 203 def disable_qt4(self):
@@ -184,6 +234,7 b' class InputHookManager(object):'
184 234 from IPython.lib.inputhookgtk import inputhook_gtk
185 235 self.set_inputhook(inputhook_gtk)
186 236 self._current_gui = 'gtk'
237 self._hijack_gtk()
187 238
188 239 def disable_gtk(self):
189 240 """Disable event loop integration with PyGTK.
@@ -206,6 +257,7 b' class InputHookManager(object):'
206 257 sets ``PyOS_InputHook``.
207 258 """
208 259 self._current_gui = 'tk'
260 self._hijack_tk()
209 261
210 262 def disable_tk(self):
211 263 """Disable event loop integration with Tkinter.
@@ -231,3 +283,4 b' disable_tk = inputhook_manager.disable_tk'
231 283 clear_inputhook = inputhook_manager.clear_inputhook
232 284 set_inputhook = inputhook_manager.set_inputhook
233 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 21 import os
22 import signal
22 23 import sys
23 24 import time
24 25 from timeit import default_timer as clock
@@ -122,6 +123,12 b' def inputhook_wx3():'
122 123 if app is not None:
123 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 132 evtloop = wx.EventLoop()
126 133 ea = wx.EventLoopActivator(evtloop)
127 134 t = clock()
@@ -140,6 +147,8 b' def inputhook_wx3():'
140 147 # 0.005 3%
141 148 # 0.01 1.5%
142 149 # 0.05 0.5%
150 if clock()-t > 1.0:
151 time.sleep(1.0)
143 152 if clock()-t > 0.1:
144 153 # Few GUI events coming in, so we can sleep longer
145 154 time.sleep(0.05)
General Comments 0
You need to be logged in to leave comments. Login now