Show More
@@ -45,17 +45,6 b' from .core.error import TryNext' | |||
|
45 | 45 | from .core.interactiveshell import InteractiveShell |
|
46 | 46 | from .testing import test |
|
47 | 47 | |
|
48 | from .lib import ( | |
|
49 | enable_wx, disable_wx, | |
|
50 | enable_gtk, disable_gtk, | |
|
51 | enable_qt4, disable_qt4, | |
|
52 | enable_tk, disable_tk, | |
|
53 | set_inputhook, clear_inputhook, | |
|
54 | current_gui, spin, | |
|
55 | appstart_qt4, appstart_wx, | |
|
56 | appstart_gtk, appstart_tk | |
|
57 | ) | |
|
58 | ||
|
59 | 48 | # Release data |
|
60 | 49 | __author__ = '' |
|
61 | 50 | for author, email in release.authors.values(): |
@@ -55,7 +55,6 b' from IPython.core.macro import Macro' | |||
|
55 | 55 | from IPython.core import page |
|
56 | 56 | from IPython.core.prefilter import ESC_MAGIC |
|
57 | 57 | from IPython.lib.pylabtools import mpl_runner |
|
58 | from IPython.lib.inputhook import enable_gui | |
|
59 | 58 | from IPython.external.Itpl import itpl, printpl |
|
60 | 59 | from IPython.testing import decorators as testdec |
|
61 | 60 | from IPython.utils.io import file_read, nlprint |
@@ -3475,7 +3474,7 b' Defaulting color scheme to \'NoColor\'"""' | |||
|
3475 | 3474 | def magic_gui(self, parameter_s=''): |
|
3476 | 3475 | """Enable or disable IPython GUI event loop integration. |
|
3477 | 3476 | |
|
3478 |
%gui [ |
|
|
3477 | %gui [GUINAME] | |
|
3479 | 3478 | |
|
3480 | 3479 | This magic replaces IPython's threaded shells that were activated |
|
3481 | 3480 | using the (pylab/wthread/etc.) command line flags. GUI toolkits |
@@ -3492,17 +3491,11 b' Defaulting color scheme to \'NoColor\'"""' | |||
|
3492 | 3491 | WARNING: after any of these has been called you can simply create |
|
3493 | 3492 | an application object, but DO NOT start the event loop yourself, as |
|
3494 | 3493 | we have already handled that. |
|
3495 | ||
|
3496 | If you want us to create an appropriate application object add the | |
|
3497 | "-a" flag to your command:: | |
|
3498 | ||
|
3499 | %gui -a wx | |
|
3500 | ||
|
3501 | This is highly recommended for most users. | |
|
3502 | 3494 | """ |
|
3503 | opts, arg = self.parse_options(parameter_s,'a') | |
|
3495 | from IPython.lib.inputhook import enable_gui | |
|
3496 | opts, arg = self.parse_options(parameter_s='') | |
|
3504 | 3497 | if arg=='': arg = None |
|
3505 |
return enable_gui(arg |
|
|
3498 | return enable_gui(arg) | |
|
3506 | 3499 | |
|
3507 | 3500 | def magic_load_ext(self, module_str): |
|
3508 | 3501 | """Load an IPython extension by its module name.""" |
@@ -21,11 +21,9 b' from IPython.lib.inputhook import (' | |||
|
21 | 21 | enable_qt4, disable_qt4, |
|
22 | 22 | enable_tk, disable_tk, |
|
23 | 23 | set_inputhook, clear_inputhook, |
|
24 |
current_gui |
|
|
25 | appstart_qt4, appstart_wx, | |
|
26 | appstart_gtk, appstart_tk | |
|
24 | current_gui | |
|
27 | 25 | ) |
|
28 | 26 | |
|
29 | 27 | #----------------------------------------------------------------------------- |
|
30 | 28 | # Code |
|
31 | #----------------------------------------------------------------------------- No newline at end of file | |
|
29 | #----------------------------------------------------------------------------- |
@@ -34,137 +34,6 b" GUI_TK = 'tk'" | |||
|
34 | 34 | #----------------------------------------------------------------------------- |
|
35 | 35 | |
|
36 | 36 | |
|
37 | class _DummyMainloop(object): | |
|
38 | """A special manager to hijack GUI mainloops that is mostly a no-op. | |
|
39 | ||
|
40 | We are not using this class currently as it breaks GUI code that calls | |
|
41 | a mainloop function after the app has started to process pending events. | |
|
42 | """ | |
|
43 | def __init__(self, ml, ihm, gui_type): | |
|
44 | self.ml = ml | |
|
45 | self.ihm = ihm | |
|
46 | self.gui_type = gui_type | |
|
47 | ||
|
48 | def __call__(self, *args, **kw): | |
|
49 | if self.ihm.current_gui() == self.gui_type: | |
|
50 | pass | |
|
51 | else: | |
|
52 | self.ml(*args, **kw) | |
|
53 | ||
|
54 | ||
|
55 | #----------------------------------------------------------------------------- | |
|
56 | # Appstart and spin functions | |
|
57 | #----------------------------------------------------------------------------- | |
|
58 | ||
|
59 | ||
|
60 | def appstart_qt4(app): | |
|
61 | """Start the qt4 event loop in a way that plays with IPython. | |
|
62 | ||
|
63 | When a qt4 app is run interactively in IPython, the event loop should | |
|
64 | not be started. This function checks to see if IPython's qt4 integration | |
|
65 | is activated and if so, it passes. If not, it will call the :meth:`exec_` | |
|
66 | method of the main qt4 app. | |
|
67 | ||
|
68 | This function should be used by users who want their qt4 scripts to work | |
|
69 | both at the command line and in IPython. These users should put the | |
|
70 | following logic at the bottom on their script, after they create a | |
|
71 | :class:`QApplication` instance (called ``app`` here):: | |
|
72 | ||
|
73 | try: | |
|
74 | from IPython.lib.inputhook import appstart_qt4 | |
|
75 | appstart_qt4(app) | |
|
76 | except ImportError: | |
|
77 | app.exec_() | |
|
78 | """ | |
|
79 | from PyQt4 import QtCore | |
|
80 | ||
|
81 | assert isinstance(app, QtCore.QCoreApplication) | |
|
82 | if app is not None: | |
|
83 | if current_gui() == GUI_QT4: | |
|
84 | pass | |
|
85 | else: | |
|
86 | app.exec_() | |
|
87 | ||
|
88 | ||
|
89 | def appstart_wx(app): | |
|
90 | """Start the wx event loop in a way that plays with IPython. | |
|
91 | ||
|
92 | When a wx app is run interactively in IPython, the event loop should | |
|
93 | not be started. This function checks to see if IPython's wx integration | |
|
94 | is activated and if so, it passes. If not, it will call the | |
|
95 | :meth:`MainLoop` method of the main qt4 app. | |
|
96 | ||
|
97 | This function should be used by users who want their wx scripts to work | |
|
98 | both at the command line and in IPython. These users should put the | |
|
99 | following logic at the bottom on their script, after they create a | |
|
100 | :class:`App` instance (called ``app`` here):: | |
|
101 | ||
|
102 | try: | |
|
103 | from IPython.lib.inputhook import appstart_wx | |
|
104 | appstart_wx(app) | |
|
105 | except ImportError: | |
|
106 | app.MainLoop() | |
|
107 | """ | |
|
108 | import wx | |
|
109 | ||
|
110 | assert isinstance(app, wx.App) | |
|
111 | if app is not None: | |
|
112 | if current_gui() == GUI_WX: | |
|
113 | pass | |
|
114 | else: | |
|
115 | app.MainLoop() | |
|
116 | ||
|
117 | ||
|
118 | def appstart_tk(app): | |
|
119 | """Start the tk event loop in a way that plays with IPython. | |
|
120 | ||
|
121 | When a tk app is run interactively in IPython, the event loop should | |
|
122 | not be started. This function checks to see if IPython's tk integration | |
|
123 | is activated and if so, it passes. If not, it will call the | |
|
124 | :meth:`mainloop` method of the tk object passed to this method. | |
|
125 | ||
|
126 | This function should be used by users who want their tk scripts to work | |
|
127 | both at the command line and in IPython. These users should put the | |
|
128 | following logic at the bottom on their script, after they create a | |
|
129 | :class:`Tk` instance (called ``app`` here):: | |
|
130 | ||
|
131 | try: | |
|
132 | from IPython.lib.inputhook import appstart_tk | |
|
133 | appstart_tk(app) | |
|
134 | except ImportError: | |
|
135 | app.mainloop() | |
|
136 | """ | |
|
137 | if app is not None: | |
|
138 | if current_gui() == GUI_TK: | |
|
139 | pass | |
|
140 | else: | |
|
141 | app.mainloop() | |
|
142 | ||
|
143 | def appstart_gtk(): | |
|
144 | """Start the gtk event loop in a way that plays with IPython. | |
|
145 | ||
|
146 | When a gtk app is run interactively in IPython, the event loop should | |
|
147 | not be started. This function checks to see if IPython's gtk integration | |
|
148 | is activated and if so, it passes. If not, it will call | |
|
149 | :func:`gtk.main`. Unlike the other appstart implementations, this does | |
|
150 | not take an ``app`` argument. | |
|
151 | ||
|
152 | This function should be used by users who want their gtk scripts to work | |
|
153 | both at the command line and in IPython. These users should put the | |
|
154 | following logic at the bottom on their script:: | |
|
155 | ||
|
156 | try: | |
|
157 | from IPython.lib.inputhook import appstart_gtk | |
|
158 | appstart_gtk() | |
|
159 | except ImportError: | |
|
160 | gtk.main() | |
|
161 | """ | |
|
162 | import gtk | |
|
163 | if current_gui() == GUI_GTK: | |
|
164 | pass | |
|
165 | else: | |
|
166 | gtk.main() | |
|
167 | ||
|
168 | 37 | #----------------------------------------------------------------------------- |
|
169 | 38 | # Main InputHookManager class |
|
170 | 39 | #----------------------------------------------------------------------------- |
@@ -180,11 +49,6 b' class InputHookManager(object):' | |||
|
180 | 49 | def __init__(self): |
|
181 | 50 | self.PYFUNC = ctypes.PYFUNCTYPE(ctypes.c_int) |
|
182 | 51 | self._apps = {} |
|
183 | self._spinner_dict = { | |
|
184 | GUI_QT4 : self._spin_qt4, | |
|
185 | GUI_WX : self._spin_wx, | |
|
186 | GUI_GTK : self._spin_gtk, | |
|
187 | GUI_TK : self._spin_tk} | |
|
188 | 52 | self._reset() |
|
189 | 53 | |
|
190 | 54 | def _reset(self): |
@@ -193,122 +57,6 b' class InputHookManager(object):' | |||
|
193 | 57 | self._installed = False |
|
194 | 58 | self._current_gui = None |
|
195 | 59 | |
|
196 | def _hijack_wx(self): | |
|
197 | """Hijack the wx mainloop so a user calling it won't cause badness. | |
|
198 | ||
|
199 | We are not currently using this as it breaks GUI code that calls a | |
|
200 | mainloop at anytime but startup. | |
|
201 | """ | |
|
202 | import wx | |
|
203 | if hasattr(wx, '_core_'): core = getattr(wx, '_core_') | |
|
204 | elif hasattr(wx, '_core'): core = getattr(wx, '_core') | |
|
205 | else: raise AttributeError('Could not find wx core module') | |
|
206 | orig_mainloop = core.PyApp_MainLoop | |
|
207 | core.PyApp_MainLoop = _DummyMainloop | |
|
208 | return orig_mainloop | |
|
209 | ||
|
210 | def _hijack_qt4(self): | |
|
211 | """Hijack the qt4 mainloop so a user calling it won't cause badness. | |
|
212 | ||
|
213 | We are not currently using this as it breaks GUI code that calls a | |
|
214 | mainloop at anytime but startup. | |
|
215 | """ | |
|
216 | from PyQt4 import QtGui, QtCore | |
|
217 | orig_mainloop = QtGui.qApp.exec_ | |
|
218 | dumb_ml = _DummyMainloop(orig_mainloop, self, GUI_QT4) | |
|
219 | QtGui.qApp.exec_ = dumb_ml | |
|
220 | QtGui.QApplication.exec_ = dumb_ml | |
|
221 | QtCore.QCoreApplication.exec_ = dumb_ml | |
|
222 | return orig_mainloop | |
|
223 | ||
|
224 | def _hijack_gtk(self): | |
|
225 | """Hijack the gtk mainloop so a user calling it won't cause badness. | |
|
226 | ||
|
227 | We are not currently using this as it breaks GUI code that calls a | |
|
228 | mainloop at anytime but startup. | |
|
229 | """ | |
|
230 | import gtk | |
|
231 | orig_mainloop = gtk.main | |
|
232 | dumb_ml = _DummyMainloop(orig_mainloop, self, GUI_GTK) | |
|
233 | gtk.mainloop = dumb_ml | |
|
234 | gtk.main = dumb_ml | |
|
235 | return orig_mainloop | |
|
236 | ||
|
237 | def _hijack_tk(self): | |
|
238 | """Hijack the tk mainloop so a user calling it won't cause badness. | |
|
239 | ||
|
240 | We are not currently using this as it breaks GUI code that calls a | |
|
241 | mainloop at anytime but startup. | |
|
242 | """ | |
|
243 | import Tkinter | |
|
244 | # FIXME: gtk is not imported here and we shouldn't be using gtk.main! | |
|
245 | orig_mainloop = gtk.main | |
|
246 | dumb_ml = _DummyMainloop(orig_mainloop, self, GUI_TK) | |
|
247 | Tkinter.Misc.mainloop = dumb_ml | |
|
248 | Tkinter.mainloop = dumb_ml | |
|
249 | ||
|
250 | def _spin_qt4(self): | |
|
251 | """Process all pending events in the qt4 event loop. | |
|
252 | ||
|
253 | This is for internal IPython use only and user code should not call this. | |
|
254 | Instead, they should issue the raw GUI calls themselves. | |
|
255 | """ | |
|
256 | from PyQt4 import QtCore | |
|
257 | ||
|
258 | app = QtCore.QCoreApplication.instance() | |
|
259 | if app is not None: | |
|
260 | QtCore.QCoreApplication.processEvents(QtCore.QEventLoop.AllEvents) | |
|
261 | ||
|
262 | def _spin_wx(self): | |
|
263 | """Process all pending events in the wx event loop. | |
|
264 | ||
|
265 | This is for internal IPython use only and user code should not call this. | |
|
266 | Instead, they should issue the raw GUI calls themselves. | |
|
267 | """ | |
|
268 | import wx | |
|
269 | app = wx.GetApp() | |
|
270 | if app is not None and wx.Thread_IsMain(): | |
|
271 | evtloop = wx.EventLoop() | |
|
272 | ea = wx.EventLoopActivator(evtloop) | |
|
273 | while evtloop.Pending(): | |
|
274 | evtloop.Dispatch() | |
|
275 | app.ProcessIdle() | |
|
276 | del ea | |
|
277 | ||
|
278 | def _spin_gtk(self): | |
|
279 | """Process all pending events in the gtk event loop. | |
|
280 | ||
|
281 | This is for internal IPython use only and user code should not call this. | |
|
282 | Instead, they should issue the raw GUI calls themselves. | |
|
283 | """ | |
|
284 | import gtk | |
|
285 | gtk.gdk.threads_enter() | |
|
286 | while gtk.events_pending(): | |
|
287 | gtk.main_iteration(False) | |
|
288 | gtk.gdk.flush() | |
|
289 | gtk.gdk.threads_leave() | |
|
290 | ||
|
291 | def _spin_tk(self): | |
|
292 | """Process all pending events in the tk event loop. | |
|
293 | ||
|
294 | This is for internal IPython use only and user code should not call this. | |
|
295 | Instead, they should issue the raw GUI calls themselves. | |
|
296 | """ | |
|
297 | app = self._apps.get(GUI_TK) | |
|
298 | if app is not None: | |
|
299 | app.update() | |
|
300 | ||
|
301 | def spin(self): | |
|
302 | """Process pending events in the current gui. | |
|
303 | ||
|
304 | This method is just provided for IPython to use internally if needed | |
|
305 | for things like testing. Third party projects should not call this | |
|
306 | method, but instead should call the underlying GUI toolkit methods | |
|
307 | that we are calling. | |
|
308 | """ | |
|
309 | spinner = self._spinner_dict.get(self._current_gui, lambda: None) | |
|
310 | spinner() | |
|
311 | ||
|
312 | 60 | def get_pyos_inputhook(self): |
|
313 | 61 | """Return the current PyOS_InputHook as a ctypes.c_void_p.""" |
|
314 | 62 | return ctypes.c_void_p.in_dll(ctypes.pythonapi,"PyOS_InputHook") |
@@ -365,7 +113,7 b' class InputHookManager(object):' | |||
|
365 | 113 | elif self._apps.has_key(gui): |
|
366 | 114 | del self._apps[gui] |
|
367 | 115 | |
|
368 |
def enable_wx(self |
|
|
116 | def enable_wx(self): | |
|
369 | 117 | """Enable event loop integration with wxPython. |
|
370 | 118 | |
|
371 | 119 | Parameters |
@@ -393,22 +141,24 b' class InputHookManager(object):' | |||
|
393 | 141 | from IPython.lib.inputhookwx import inputhook_wx |
|
394 | 142 | self.set_inputhook(inputhook_wx) |
|
395 | 143 | self._current_gui = GUI_WX |
|
396 |
i |
|
|
397 | import wx | |
|
398 | app = wx.GetApp() | |
|
399 | if app is None: | |
|
400 | app = wx.App(redirect=False, clearSigInt=False) | |
|
401 |
|
|
|
402 |
|
|
|
144 | import wx | |
|
145 | app = wx.GetApp() | |
|
146 | if app is None: | |
|
147 | app = wx.App(redirect=False, clearSigInt=False) | |
|
148 | app._in_event_loop = True | |
|
149 | self._apps[GUI_WX] = app | |
|
150 | return app | |
|
403 | 151 | |
|
404 | 152 | def disable_wx(self): |
|
405 | 153 | """Disable event loop integration with wxPython. |
|
406 | 154 | |
|
407 | 155 | This merely sets PyOS_InputHook to NULL. |
|
408 | 156 | """ |
|
157 | if self._apps.has_key(GUI_WX): | |
|
158 | self._apps[GUI_WX]._in_event_loop = False | |
|
409 | 159 | self.clear_inputhook() |
|
410 | 160 | |
|
411 |
def enable_qt4(self |
|
|
161 | def enable_qt4(self): | |
|
412 | 162 | """Enable event loop integration with PyQt4. |
|
413 | 163 | |
|
414 | 164 | Parameters |
@@ -440,19 +190,21 b' class InputHookManager(object):' | |||
|
440 | 190 | except AttributeError: |
|
441 | 191 | pass |
|
442 | 192 | self._current_gui = GUI_QT4 |
|
443 | if app: | |
|
444 | from PyQt4 import QtGui | |
|
445 | app = QtCore.QCoreApplication.instance() | |
|
446 | if app is None: | |
|
447 | app = QtGui.QApplication(sys.argv) | |
|
448 |
|
|
|
449 |
|
|
|
193 | from PyQt4 import QtGui | |
|
194 | app = QtCore.QCoreApplication.instance() | |
|
195 | if app is None: | |
|
196 | app = QtGui.QApplication([" "]) | |
|
197 | app._in_event_loop = True | |
|
198 | self._apps[GUI_QT4] = app | |
|
199 | return app | |
|
450 | 200 | |
|
451 | 201 | def disable_qt4(self): |
|
452 | 202 | """Disable event loop integration with PyQt4. |
|
453 | 203 | |
|
454 | 204 | This merely sets PyOS_InputHook to NULL. |
|
455 | 205 | """ |
|
206 | if self._apps.has_key(GUI_QT4): | |
|
207 | self._apps[GUI_QT4]._in_event_loop = False | |
|
456 | 208 | self.clear_inputhook() |
|
457 | 209 | |
|
458 | 210 | def enable_gtk(self, app=False): |
@@ -533,11 +285,10 b' clear_inputhook = inputhook_manager.clear_inputhook' | |||
|
533 | 285 | set_inputhook = inputhook_manager.set_inputhook |
|
534 | 286 | current_gui = inputhook_manager.current_gui |
|
535 | 287 | clear_app_refs = inputhook_manager.clear_app_refs |
|
536 | spin = inputhook_manager.spin | |
|
537 | 288 | |
|
538 | 289 | |
|
539 | 290 | # Convenience function to switch amongst them |
|
540 |
def enable_gui(gui=None |
|
|
291 | def enable_gui(gui=None): | |
|
541 | 292 | """Switch amongst GUI input hooks by name. |
|
542 | 293 | |
|
543 | 294 | This is just a utility wrapper around the methods of the InputHookManager |
@@ -569,4 +320,5 b' def enable_gui(gui=None, app=True):' | |||
|
569 | 320 | except KeyError: |
|
570 | 321 | e="Invalid GUI request %r, valid ones are:%s" % (gui, guis.keys()) |
|
571 | 322 | raise ValueError(e) |
|
572 |
return gui_hook( |
|
|
323 | return gui_hook() | |
|
324 |
@@ -3,7 +3,9 b'' | |||
|
3 | 3 | |
|
4 | 4 | Authors |
|
5 | 5 | ------- |
|
6 | Fernando Perez. | |
|
6 | ||
|
7 | * Fernando Perez. | |
|
8 | * Brian Granger | |
|
7 | 9 | """ |
|
8 | 10 | |
|
9 | 11 | #----------------------------------------------------------------------------- |
@@ -177,3 +179,4 b' def mpl_runner(safe_execfile):' | |||
|
177 | 179 | pylab.draw_if_interactive.called = False |
|
178 | 180 | |
|
179 | 181 | return mpl_execfile |
|
182 |
@@ -374,6 +374,11 b' class ZMQInteractiveShell(InteractiveShell):' | |||
|
374 | 374 | } |
|
375 | 375 | self.payload_manager.write_payload(payload) |
|
376 | 376 | |
|
377 | def magic_gui(self, *args, **kwargs): | |
|
378 | raise NotImplementedError('GUI support must be enabled in command line options.') | |
|
379 | ||
|
380 | def magic_pylab(self, *args, **kwargs): | |
|
381 | raise NotImplementedError('pylab support must be enabled in commandl in options.') | |
|
377 | 382 | |
|
378 | 383 | def _showtraceback(self, etype, evalue, stb): |
|
379 | 384 |
General Comments 0
You need to be logged in to leave comments.
Login now