Show More
@@ -0,0 +1,99 b'' | |||||
|
1 | """A Simple wx example to test IPython's event loop integration. | |||
|
2 | ||||
|
3 | To run this do: | |||
|
4 | ||||
|
5 | In [5]: %gui wx | |||
|
6 | ||||
|
7 | In [6]: %run gui-wx.py | |||
|
8 | ||||
|
9 | Ref: Modified from wxPython source code wxPython/samples/simple/simple.py | |||
|
10 | ||||
|
11 | This example can only be run once in a given IPython session. | |||
|
12 | """ | |||
|
13 | ||||
|
14 | import wx | |||
|
15 | ||||
|
16 | ||||
|
17 | class MyFrame(wx.Frame): | |||
|
18 | """ | |||
|
19 | This is MyFrame. It just shows a few controls on a wxPanel, | |||
|
20 | and has a simple menu. | |||
|
21 | """ | |||
|
22 | def __init__(self, parent, title): | |||
|
23 | wx.Frame.__init__(self, parent, -1, title, | |||
|
24 | pos=(150, 150), size=(350, 200)) | |||
|
25 | ||||
|
26 | # Create the menubar | |||
|
27 | menuBar = wx.MenuBar() | |||
|
28 | ||||
|
29 | # and a menu | |||
|
30 | menu = wx.Menu() | |||
|
31 | ||||
|
32 | # add an item to the menu, using \tKeyName automatically | |||
|
33 | # creates an accelerator, the third param is some help text | |||
|
34 | # that will show up in the statusbar | |||
|
35 | menu.Append(wx.ID_EXIT, "E&xit\tAlt-X", "Exit this simple sample") | |||
|
36 | ||||
|
37 | # bind the menu event to an event handler | |||
|
38 | self.Bind(wx.EVT_MENU, self.OnTimeToClose, id=wx.ID_EXIT) | |||
|
39 | ||||
|
40 | # and put the menu on the menubar | |||
|
41 | menuBar.Append(menu, "&File") | |||
|
42 | self.SetMenuBar(menuBar) | |||
|
43 | ||||
|
44 | self.CreateStatusBar() | |||
|
45 | ||||
|
46 | # Now create the Panel to put the other controls on. | |||
|
47 | panel = wx.Panel(self) | |||
|
48 | ||||
|
49 | # and a few controls | |||
|
50 | text = wx.StaticText(panel, -1, "Hello World!") | |||
|
51 | text.SetFont(wx.Font(14, wx.SWISS, wx.NORMAL, wx.BOLD)) | |||
|
52 | text.SetSize(text.GetBestSize()) | |||
|
53 | btn = wx.Button(panel, -1, "Close") | |||
|
54 | funbtn = wx.Button(panel, -1, "Just for fun...") | |||
|
55 | ||||
|
56 | # bind the button events to handlers | |||
|
57 | self.Bind(wx.EVT_BUTTON, self.OnTimeToClose, btn) | |||
|
58 | self.Bind(wx.EVT_BUTTON, self.OnFunButton, funbtn) | |||
|
59 | ||||
|
60 | # Use a sizer to layout the controls, stacked vertically and with | |||
|
61 | # a 10 pixel border around each | |||
|
62 | sizer = wx.BoxSizer(wx.VERTICAL) | |||
|
63 | sizer.Add(text, 0, wx.ALL, 10) | |||
|
64 | sizer.Add(btn, 0, wx.ALL, 10) | |||
|
65 | sizer.Add(funbtn, 0, wx.ALL, 10) | |||
|
66 | panel.SetSizer(sizer) | |||
|
67 | panel.Layout() | |||
|
68 | ||||
|
69 | ||||
|
70 | def OnTimeToClose(self, evt): | |||
|
71 | """Event handler for the button click.""" | |||
|
72 | print "See ya later!" | |||
|
73 | self.Close() | |||
|
74 | ||||
|
75 | def OnFunButton(self, evt): | |||
|
76 | """Event handler for the button click.""" | |||
|
77 | print "Having fun yet?" | |||
|
78 | ||||
|
79 | ||||
|
80 | class MyApp(wx.App): | |||
|
81 | def OnInit(self): | |||
|
82 | frame = MyFrame(None, "Simple wxPython App") | |||
|
83 | self.SetTopWindow(frame) | |||
|
84 | ||||
|
85 | print "Print statements go to this stdout window by default." | |||
|
86 | ||||
|
87 | frame.Show(True) | |||
|
88 | return True | |||
|
89 | ||||
|
90 | app = wx.GetApp() | |||
|
91 | if app is None: | |||
|
92 | app = MyApp(redirect=False, clearSigInt=False) | |||
|
93 | ||||
|
94 | try: | |||
|
95 | from IPython.lib.inputhook import appstart_wx | |||
|
96 | appstart_wx(app) | |||
|
97 | except ImportError: | |||
|
98 | app.MainLoop() | |||
|
99 |
@@ -63,6 +63,16 b' Shell = shell' | |||||
63 | from IPython.core import ipapi |
|
63 | from IPython.core import ipapi | |
64 | from IPython.core import iplib |
|
64 | from IPython.core import iplib | |
65 |
|
65 | |||
|
66 | from IPython.lib import ( | |||
|
67 | enable_wx, disable_wx, | |||
|
68 | enable_gtk, disable_gtk, | |||
|
69 | enable_qt4, disable_qt4, | |||
|
70 | enable_tk, disable_tk, | |||
|
71 | set_inputhook, clear_inputhook, | |||
|
72 | current_gui, spin, | |||
|
73 | appstart_qt4, appstart_wx | |||
|
74 | ) | |||
|
75 | ||||
66 | # Release data |
|
76 | # Release data | |
67 | from IPython.core import release # do it explicitly so pydoc can see it - pydoc bug |
|
77 | from IPython.core import release # do it explicitly so pydoc can see it - pydoc bug | |
68 | __author__ = '%s <%s>\n%s <%s>\n%s <%s>' % \ |
|
78 | __author__ = '%s <%s>\n%s <%s>\n%s <%s>' % \ |
@@ -20,7 +20,9 b' from IPython.lib.inputhook import (' | |||||
20 | enable_gtk, disable_gtk, |
|
20 | enable_gtk, disable_gtk, | |
21 | enable_qt4, disable_qt4, |
|
21 | enable_qt4, disable_qt4, | |
22 | enable_tk, disable_tk, |
|
22 | enable_tk, disable_tk, | |
23 | set_inputhook, clear_inputhook |
|
23 | set_inputhook, clear_inputhook, | |
|
24 | current_gui, spin, | |||
|
25 | appstart_qt4, appstart_wx | |||
24 | ) |
|
26 | ) | |
25 |
|
27 | |||
26 | #----------------------------------------------------------------------------- |
|
28 | #----------------------------------------------------------------------------- |
@@ -19,70 +19,104 b' import ctypes' | |||||
19 | import sys |
|
19 | import sys | |
20 |
|
20 | |||
21 | #----------------------------------------------------------------------------- |
|
21 | #----------------------------------------------------------------------------- | |
22 | # Code |
|
22 | # Constants | |
|
23 | #----------------------------------------------------------------------------- | |||
|
24 | ||||
|
25 | # Constants for identifying the GUI toolkits. | |||
|
26 | GUI_WX = 'wx' | |||
|
27 | GUI_QT4 = 'qt4' | |||
|
28 | GUI_GTK = 'gtk' | |||
|
29 | GUI_TK = 'tk' | |||
|
30 | ||||
|
31 | #----------------------------------------------------------------------------- | |||
|
32 | # Utility classes | |||
23 | #----------------------------------------------------------------------------- |
|
33 | #----------------------------------------------------------------------------- | |
24 |
|
34 | |||
25 | def appstart_qt4(): |
|
|||
26 | from PyQt4 import QtCore, QtGui |
|
|||
27 |
|
||||
28 | app = QtCore.QCoreApplication.instance() |
|
|||
29 | print 'qtapp:', app |
|
|||
30 | if app is not None: |
|
|||
31 | if current_gui() == 'qt4': |
|
|||
32 | pass |
|
|||
33 | else: |
|
|||
34 | app.exec_() |
|
|||
35 |
|
||||
36 |
|
35 | |||
37 | class _DummyMainloop(object): |
|
36 | class _DummyMainloop(object): | |
38 | """A special manager to hijack GUI mainloops that is mostly a no-op. |
|
37 | """A special manager to hijack GUI mainloops that is mostly a no-op. | |
39 |
|
38 | |||
40 | This does have, however, special logic. |
|
39 | We are not using this class currently as it breaks GUI code that calls | |
|
40 | a mainloop function after the app has started to process pending events. | |||
41 | """ |
|
41 | """ | |
42 | def __init__(self, ml, ihm, gui_type): |
|
42 | def __init__(self, ml, ihm, gui_type): | |
43 | self.ml = ml |
|
43 | self.ml = ml | |
44 | self.ihm = ihm |
|
44 | self.ihm = ihm | |
45 | self.gui_type = gui_type |
|
45 | self.gui_type = gui_type | |
46 |
|
46 | |||
47 |
|
||||
48 | def __call__(self, *args, **kw): |
|
47 | def __call__(self, *args, **kw): | |
49 | force = kw.pop('force', False) |
|
|||
50 | force = False |
|
|||
51 | if force: |
|
|||
52 | #print 'forced spin' # dbg |
|
|||
53 | self.ml(*args, **kw) |
|
|||
54 |
|
||||
55 | if self.ihm.current_gui() == self.gui_type: |
|
48 | if self.ihm.current_gui() == self.gui_type: | |
56 | pass |
|
49 | pass | |
57 | else: |
|
50 | else: | |
58 | self.ml(*args, **kw) |
|
51 | self.ml(*args, **kw) | |
59 |
|
52 | |||
60 |
|
53 | |||
61 | def spin_qt4(): |
|
54 | #----------------------------------------------------------------------------- | |
|
55 | # Appstart and spin functions | |||
|
56 | #----------------------------------------------------------------------------- | |||
|
57 | ||||
|
58 | ||||
|
59 | def appstart_qt4(app): | |||
|
60 | """Start the qt4 event loop in a way that plays with IPython. | |||
|
61 | ||||
|
62 | When a qt4 app is run interactively in IPython, the event loop should | |||
|
63 | not be started. This function checks to see if IPython's qt4 integration | |||
|
64 | is activated and if so, it passes. If not, it will call the :meth:`exec_` | |||
|
65 | method of the main qt4 app. | |||
|
66 | ||||
|
67 | This function should be used by users who want their qt4 scripts to work | |||
|
68 | both at the command line and in IPython. These users should put the | |||
|
69 | following logic at the bottom on their script, after they create a | |||
|
70 | :class:`QApplication` instance (called ``app`` here):: | |||
|
71 | ||||
|
72 | try: | |||
|
73 | from IPython.lib.inputhook import appstart_qt4 | |||
|
74 | appstart_qt4(app) | |||
|
75 | except ImportError: | |||
|
76 | app.exec_() | |||
|
77 | """ | |||
62 | from PyQt4 import QtCore, QtGui |
|
78 | from PyQt4 import QtCore, QtGui | |
63 |
|
79 | |||
64 |
app |
|
80 | assert isinstance(app, QtCore.QCoreApplication) | |
65 | if (app is not None) and (app.thread() == QtCore.QThread.currentThread()): |
|
81 | if app is not None: | |
66 | ## timer = QtCore.QTimer() |
|
82 | if current_gui() == GUI_QT4: | |
67 | ## QtCore.QObject.connect(timer, |
|
83 | pass | |
68 | ## QtCore.SIGNAL('timeout()'), |
|
84 | else: | |
69 | ## app, |
|
85 | app.exec_() | |
70 | ## QtCore.SLOT('quit()')) |
|
86 | ||
71 | ## timer.start(100) |
|
87 | ||
72 | #QtCore.QCoreApplication.exec_(force=True) |
|
88 | def appstart_wx(app): | |
73 | QtCore.QCoreApplication.processEvents(QtCore.QEventLoop.AllEvents) |
|
89 | """Start the wx event loop in a way that plays with IPython. | |
74 | ##timer.stop() |
|
90 | ||
75 |
|
91 | When a wx app is run interactively in IPython, the event loop should | ||
76 |
|
92 | not be started. This function checks to see if IPython's wx integration | ||
77 | def spin_wx(): |
|
93 | is activated and if so, it passes. If not, it will call the | |
78 | app = wx.GetApp() |
|
94 | :meth:`MainLoop` method of the main qt4 app. | |
79 | if app is not None and wx.Thread_IsMain(): |
|
95 | ||
80 | evtloop = wx.EventLoop() |
|
96 | This function should be used by users who want their wx scripts to work | |
81 | ea = wx.EventLoopActivator(evtloop) |
|
97 | both at the command line and in IPython. These users should put the | |
82 | while evtloop.Pending(): |
|
98 | following logic at the bottom on their script, after they create a | |
83 | evtloop.Dispatch() |
|
99 | :class:`App` instance (called ``app`` here):: | |
84 | app.ProcessIdle() |
|
100 | ||
85 | del ea |
|
101 | try: | |
|
102 | from IPython.lib.inputhook import appstart_wx | |||
|
103 | appstart_wx(app) | |||
|
104 | except ImportError: | |||
|
105 | app.MainLoop() | |||
|
106 | """ | |||
|
107 | import wx | |||
|
108 | ||||
|
109 | assert isinstance(app, wx.App) | |||
|
110 | if app is not None: | |||
|
111 | if current_gui() == GUI_WX: | |||
|
112 | pass | |||
|
113 | else: | |||
|
114 | app.MainLoop() | |||
|
115 | ||||
|
116 | ||||
|
117 | #----------------------------------------------------------------------------- | |||
|
118 | # Main InputHookManager class | |||
|
119 | #----------------------------------------------------------------------------- | |||
86 |
|
120 | |||
87 |
|
121 | |||
88 | class InputHookManager(object): |
|
122 | class InputHookManager(object): | |
@@ -95,6 +129,11 b' class InputHookManager(object):' | |||||
95 | def __init__(self): |
|
129 | def __init__(self): | |
96 | self.PYFUNC = ctypes.PYFUNCTYPE(ctypes.c_int) |
|
130 | self.PYFUNC = ctypes.PYFUNCTYPE(ctypes.c_int) | |
97 | self._apps = {} |
|
131 | self._apps = {} | |
|
132 | self._spinner_dict = { | |||
|
133 | GUI_QT4 : self._spin_qt4, | |||
|
134 | GUI_WX : self._spin_wx, | |||
|
135 | GUI_GTK : self._spin_gtk, | |||
|
136 | GUI_TK : self._spin_tk} | |||
98 | self._reset() |
|
137 | self._reset() | |
99 |
|
138 | |||
100 | def _reset(self): |
|
139 | def _reset(self): | |
@@ -104,7 +143,11 b' class InputHookManager(object):' | |||||
104 | self._current_gui = None |
|
143 | self._current_gui = None | |
105 |
|
144 | |||
106 | def _hijack_wx(self): |
|
145 | def _hijack_wx(self): | |
107 |
"""Hijack the wx mainloop so a user calling it won't cause badness. |
|
146 | """Hijack the wx mainloop so a user calling it won't cause badness. | |
|
147 | ||||
|
148 | We are not currently using this as it breaks GUI code that calls a | |||
|
149 | mainloop at anytime but startup. | |||
|
150 | """ | |||
108 | import wx |
|
151 | import wx | |
109 | if hasattr(wx, '_core_'): core = getattr(wx, '_core_') |
|
152 | if hasattr(wx, '_core_'): core = getattr(wx, '_core_') | |
110 | elif hasattr(wx, '_core'): core = getattr(wx, '_core') |
|
153 | elif hasattr(wx, '_core'): core = getattr(wx, '_core') | |
@@ -114,28 +157,100 b' class InputHookManager(object):' | |||||
114 | return orig_mainloop |
|
157 | return orig_mainloop | |
115 |
|
158 | |||
116 | def _hijack_qt4(self): |
|
159 | def _hijack_qt4(self): | |
117 |
"""Hijack the qt4 mainloop so a user calling it won't cause badness. |
|
160 | """Hijack the qt4 mainloop so a user calling it won't cause badness. | |
|
161 | ||||
|
162 | We are not currently using this as it breaks GUI code that calls a | |||
|
163 | mainloop at anytime but startup. | |||
|
164 | """ | |||
118 | from PyQt4 import QtGui, QtCore |
|
165 | from PyQt4 import QtGui, QtCore | |
119 | orig_mainloop = QtGui.qApp.exec_ |
|
166 | orig_mainloop = QtGui.qApp.exec_ | |
120 |
dumb_ml = _DummyMainloop(orig_mainloop, self, |
|
167 | dumb_ml = _DummyMainloop(orig_mainloop, self, GUI_QT4) | |
121 | QtGui.qApp.exec_ = dumb_ml |
|
168 | QtGui.qApp.exec_ = dumb_ml | |
122 | QtGui.QApplication.exec_ = dumb_ml |
|
169 | QtGui.QApplication.exec_ = dumb_ml | |
123 | QtCore.QCoreApplication.exec_ = dumb_ml |
|
170 | QtCore.QCoreApplication.exec_ = dumb_ml | |
124 | return orig_mainloop |
|
171 | return orig_mainloop | |
125 |
|
172 | |||
126 | def _hijack_gtk(self): |
|
173 | def _hijack_gtk(self): | |
127 |
"""Hijack the gtk mainloop so a user calling it won't cause badness. |
|
174 | """Hijack the gtk mainloop so a user calling it won't cause badness. | |
|
175 | ||||
|
176 | We are not currently using this as it breaks GUI code that calls a | |||
|
177 | mainloop at anytime but startup. | |||
|
178 | """ | |||
128 | import gtk |
|
179 | import gtk | |
129 | orig_mainloop = gtk.main |
|
180 | orig_mainloop = gtk.main | |
130 | gtk.mainloop = _DummyMainloop |
|
181 | dumb_ml = _DummyMainloop(orig_mainloop, self, GUI_GTK) | |
131 |
gtk.main = |
|
182 | gtk.mainloop = dumb_ml | |
|
183 | gtk.main = dumb_ml | |||
132 | return orig_mainloop |
|
184 | return orig_mainloop | |
133 |
|
185 | |||
134 | def _hijack_tk(self): |
|
186 | def _hijack_tk(self): | |
135 |
"""Hijack the tk mainloop so a user calling it won't cause badness. |
|
187 | """Hijack the tk mainloop so a user calling it won't cause badness. | |
|
188 | ||||
|
189 | We are not currently using this as it breaks GUI code that calls a | |||
|
190 | mainloop at anytime but startup. | |||
|
191 | """ | |||
136 | import Tkinter |
|
192 | import Tkinter | |
137 |
|
|
193 | orig_mainloop = gtk.main | |
138 | Tkinter.mainloop = _DummyMainloop |
|
194 | dumb_ml = _DummyMainloop(orig_mainloop, self, GUI_TK) | |
|
195 | Tkinter.Misc.mainloop = dumb_ml | |||
|
196 | Tkinter.mainloop = dumb_ml | |||
|
197 | ||||
|
198 | def _spin_qt4(self): | |||
|
199 | """Process all pending events in the qt4 event loop. | |||
|
200 | ||||
|
201 | This is for internal IPython use only and user code should not call this. | |||
|
202 | Instead, they should issue the raw GUI calls themselves. | |||
|
203 | """ | |||
|
204 | from PyQt4 import QtCore, QtGui | |||
|
205 | ||||
|
206 | app = QtCore.QCoreApplication.instance() | |||
|
207 | if app is not None: | |||
|
208 | QtCore.QCoreApplication.processEvents(QtCore.QEventLoop.AllEvents) | |||
|
209 | ||||
|
210 | def _spin_wx(self): | |||
|
211 | """Process all pending events in the wx event loop. | |||
|
212 | ||||
|
213 | This is for internal IPython use only and user code should not call this. | |||
|
214 | Instead, they should issue the raw GUI calls themselves. | |||
|
215 | """ | |||
|
216 | import wx | |||
|
217 | app = wx.GetApp() | |||
|
218 | if app is not None and wx.Thread_IsMain(): | |||
|
219 | evtloop = wx.EventLoop() | |||
|
220 | ea = wx.EventLoopActivator(evtloop) | |||
|
221 | while evtloop.Pending(): | |||
|
222 | evtloop.Dispatch() | |||
|
223 | app.ProcessIdle() | |||
|
224 | del ea | |||
|
225 | ||||
|
226 | def _spin_gtk(self): | |||
|
227 | """Process all pending events in the gtk event loop. | |||
|
228 | ||||
|
229 | This is for internal IPython use only and user code should not call this. | |||
|
230 | Instead, they should issue the raw GUI calls themselves. | |||
|
231 | """ | |||
|
232 | pass | |||
|
233 | ||||
|
234 | def _spin_tk(self): | |||
|
235 | """Process all pending events in the tk event loop. | |||
|
236 | ||||
|
237 | This is for internal IPython use only and user code should not call this. | |||
|
238 | Instead, they should issue the raw GUI calls themselves. | |||
|
239 | """ | |||
|
240 | app = self._apps.get(GUI_TK) | |||
|
241 | if app is not None: | |||
|
242 | app.update() | |||
|
243 | ||||
|
244 | def spin(self): | |||
|
245 | """Process pending events in the current gui. | |||
|
246 | ||||
|
247 | This method is just provided for IPython to use internally if needed | |||
|
248 | for things like testing. Third party projects should not call this | |||
|
249 | method, but instead should call the underlying GUI toolkit methods | |||
|
250 | that we are calling. | |||
|
251 | """ | |||
|
252 | spinner = self._spinner_dict.get(self._current_gui, lambda: None) | |||
|
253 | spinner() | |||
139 |
|
254 | |||
140 | def get_pyos_inputhook(self): |
|
255 | def get_pyos_inputhook(self): | |
141 | """Return the current PyOS_InputHook as a ctypes.c_void_p.""" |
|
256 | """Return the current PyOS_InputHook as a ctypes.c_void_p.""" | |
@@ -211,14 +326,13 b' class InputHookManager(object):' | |||||
211 | """ |
|
326 | """ | |
212 | from IPython.lib.inputhookwx import inputhook_wx |
|
327 | from IPython.lib.inputhookwx import inputhook_wx | |
213 | self.set_inputhook(inputhook_wx) |
|
328 | self.set_inputhook(inputhook_wx) | |
214 |
self._current_gui = |
|
329 | self._current_gui = GUI_WX | |
215 | self._hijack_wx() |
|
|||
216 | if app: |
|
330 | if app: | |
217 | import wx |
|
331 | import wx | |
218 | app = wx.GetApp() |
|
332 | app = wx.GetApp() | |
219 | if app is None: |
|
333 | if app is None: | |
220 | app = wx.App(redirect=False, clearSigInt=False) |
|
334 | app = wx.App(redirect=False, clearSigInt=False) | |
221 |
self._apps[ |
|
335 | self._apps[GUI_WX] = app | |
222 | return app |
|
336 | return app | |
223 |
|
337 | |||
224 | def disable_wx(self): |
|
338 | def disable_wx(self): | |
@@ -259,14 +373,13 b' class InputHookManager(object):' | |||||
259 | QtCore.pyqtRestoreInputHook() |
|
373 | QtCore.pyqtRestoreInputHook() | |
260 | except AttributeError: |
|
374 | except AttributeError: | |
261 | pass |
|
375 | pass | |
262 |
self._current_gui = |
|
376 | self._current_gui = GUI_QT4 | |
263 | #self._hijack_qt4() |
|
|||
264 | if app: |
|
377 | if app: | |
265 | from PyQt4 import QtGui |
|
378 | from PyQt4 import QtGui | |
266 | app = QtCore.QCoreApplication.instance() |
|
379 | app = QtCore.QCoreApplication.instance() | |
267 | if app is None: |
|
380 | if app is None: | |
268 | app = QtGui.QApplication(sys.argv) |
|
381 | app = QtGui.QApplication(sys.argv) | |
269 |
self._apps[ |
|
382 | self._apps[GUI_QT4] = app | |
270 | return app |
|
383 | return app | |
271 |
|
384 | |||
272 | def disable_qt4(self): |
|
385 | def disable_qt4(self): | |
@@ -294,13 +407,12 b' class InputHookManager(object):' | |||||
294 | import gtk |
|
407 | import gtk | |
295 | try: |
|
408 | try: | |
296 | gtk.set_interactive(True) |
|
409 | gtk.set_interactive(True) | |
297 |
self._current_gui = |
|
410 | self._current_gui = GUI_GTK | |
298 | except AttributeError: |
|
411 | except AttributeError: | |
299 | # For older versions of gtk, use our own ctypes version |
|
412 | # For older versions of gtk, use our own ctypes version | |
300 | from IPython.lib.inputhookgtk import inputhook_gtk |
|
413 | from IPython.lib.inputhookgtk import inputhook_gtk | |
301 | self.set_inputhook(inputhook_gtk) |
|
414 | self.set_inputhook(inputhook_gtk) | |
302 |
self._current_gui = |
|
415 | self._current_gui = GUI_GTK | |
303 | self._hijack_gtk() |
|
|||
304 |
|
416 | |||
305 | def disable_gtk(self): |
|
417 | def disable_gtk(self): | |
306 | """Disable event loop integration with PyGTK. |
|
418 | """Disable event loop integration with PyGTK. | |
@@ -322,8 +434,13 b' class InputHookManager(object):' | |||||
322 | Currently this is a no-op as creating a :class:`Tkinter.Tk` object |
|
434 | Currently this is a no-op as creating a :class:`Tkinter.Tk` object | |
323 | sets ``PyOS_InputHook``. |
|
435 | sets ``PyOS_InputHook``. | |
324 | """ |
|
436 | """ | |
325 |
self._current_gui = |
|
437 | self._current_gui = GUI_TK | |
326 | self._hijack_tk() |
|
438 | if app: | |
|
439 | import Tkinter | |||
|
440 | app = Tkinter.Tk() | |||
|
441 | app.withdraw() | |||
|
442 | self._apps[GUI_TK] = app | |||
|
443 | return app | |||
327 |
|
444 | |||
328 | def disable_tk(self): |
|
445 | def disable_tk(self): | |
329 | """Disable event loop integration with Tkinter. |
|
446 | """Disable event loop integration with Tkinter. | |
@@ -350,3 +467,4 b' clear_inputhook = inputhook_manager.clear_inputhook' | |||||
350 | set_inputhook = inputhook_manager.set_inputhook |
|
467 | set_inputhook = inputhook_manager.set_inputhook | |
351 | current_gui = inputhook_manager.current_gui |
|
468 | current_gui = inputhook_manager.current_gui | |
352 | clear_app_refs = inputhook_manager.clear_app_refs |
|
469 | clear_app_refs = inputhook_manager.clear_app_refs | |
|
470 | spin = inputhook_manager.spin |
@@ -35,8 +35,6 b" if __name__ == '__main__':" | |||||
35 | sw.show() |
|
35 | sw.show() | |
36 |
|
36 | |||
37 | try: |
|
37 | try: | |
38 |
import |
|
38 | from IPython import appstart_qt4; appstart_qt4(app) | |
39 | except ImportError: |
|
39 | except ImportError: | |
40 | app.exec_() |
|
40 | app.exec_() | |
41 |
|
||||
42 | #import time; time.sleep(10) |
|
@@ -1,6 +1,8 b'' | |||||
1 | """Test the new %gui command. Run this in ipython as |
|
1 | """Test the new %gui command. Run this in ipython as | |
2 |
|
2 | |||
3 |
|
|
3 | In [1]: %gui [backend] | |
|
4 | ||||
|
5 | In [2]: %run switchgui [backend] | |||
4 |
|
6 | |||
5 | where the optional backend can be one of: qt4, gtk, tk, wx. |
|
7 | where the optional backend can be one of: qt4, gtk, tk, wx. | |
6 | """ |
|
8 | """ | |
@@ -8,23 +10,18 b' where the optional backend can be one of: qt4, gtk, tk, wx.' | |||||
8 | import sys |
|
10 | import sys | |
9 | import time |
|
11 | import time | |
10 |
|
12 | |||
11 | import IPython.core.ipapi as ipapi |
|
|||
12 | ip = ipapi.get() |
|
|||
13 |
|
||||
14 | from IPython.lib import inputhook |
|
13 | from IPython.lib import inputhook | |
15 |
|
14 | |||
16 | try: |
|
15 | gui = inputhook.current_gui() | |
17 | backend = sys.argv[1] |
|
16 | if gui is None: | |
18 | #a = ip.magic('gui -a %s' % backend) |
|
17 | gui = 'qt4' | |
19 | #a = ip.magic('gui %s' % backend) |
|
18 | inputhook.enable_qt4(app=True) | |
20 | except IndexError: |
|
|||
21 | backend = 'qt' |
|
|||
22 |
|
19 | |||
23 | backends = dict(wx='wxagg', qt='qt4agg', gtk='gtkagg', tk='tkagg') |
|
20 | backends = dict(wx='wxagg', qt4='qt4agg', gtk='gtkagg', tk='tkagg') | |
24 |
|
21 | |||
25 | import matplotlib |
|
22 | import matplotlib | |
26 |
matplotlib.use(backends[ |
|
23 | matplotlib.use(backends[gui]) | |
27 |
|
|
24 | matplotlib.interactive(True) | |
28 |
|
25 | |||
29 | import matplotlib |
|
26 | import matplotlib | |
30 | from matplotlib import pyplot as plt, mlab, pylab |
|
27 | from matplotlib import pyplot as plt, mlab, pylab | |
@@ -33,25 +30,19 b' import numpy as np' | |||||
33 | from numpy import * |
|
30 | from numpy import * | |
34 | from matplotlib.pyplot import * |
|
31 | from matplotlib.pyplot import * | |
35 |
|
32 | |||
36 |
x = np.linspace(0,pi, |
|
33 | x = np.linspace(0,pi,500) | |
37 |
|
34 | |||
38 | print "A plot has been created" |
|
35 | print "A plot has been created" | |
39 | line, = plot(x,sin(2*x)) |
|
36 | line, = plot(x,sin(2*x)) | |
40 | plt.show() |
|
37 | inputhook.spin() | |
41 | inputhook.spin_qt4() |
|
|||
42 |
|
38 | |||
43 | #raw_input("Press Enter to continue") |
|
|||
44 |
|
39 | |||
45 | print "I will now count until 10, please hit Ctrl-C before I'm done..." |
|
40 | print "Now, we will update the plot..." | |
46 | print "IPython should stop counting and return to the prompt without crashing." |
|
|||
47 |
|
41 | |||
48 | line_x = line.get_data()[0] |
|
|||
49 | for i in range(1,51): |
|
42 | for i in range(1,51): | |
50 | print i, |
|
43 | print i, | |
51 | sys.stdout.flush() |
|
44 | sys.stdout.flush() | |
52 |
line.set_data( |
|
45 | line.set_data(x,sin(x*i)) | |
53 | plt.title('i=%d' % i) |
|
46 | plt.title('i=%d' % i) | |
54 | #plt.show() |
|
|||
55 | plt.draw() |
|
47 | plt.draw() | |
56 |
inputhook.spin |
|
48 | inputhook.spin() | |
57 | #time.sleep(0.04) |
|
General Comments 0
You need to be logged in to leave comments.
Login now