##// END OF EJS Templates
GUI support for wx, qt and tk.
Brian Granger -
Show More
@@ -35,8 +35,11 b' def main():'
35 group = parser.add_mutually_exclusive_group()
35 group = parser.add_mutually_exclusive_group()
36 group.add_argument('--pure', action='store_true', help = \
36 group.add_argument('--pure', action='store_true', help = \
37 'use a pure Python kernel instead of an IPython kernel')
37 'use a pure Python kernel instead of an IPython kernel')
38 group.add_argument('--pylab', action='store_true',
38 group.add_argument('--pylab', type=str, metavar='GUI', nargs='?',
39 help='use a kernel with PyLab enabled')
39 const='auto', help = \
40 "Pre-load matplotlib and numpy for interactive use. If GUI is not \
41 given, the GUI backend is matplotlib's, otherwise use one of: \
42 ['tk', 'gtk', 'qt', 'wx', 'payload-svg'].")
40 parser.add_argument('--rich', action='store_true',
43 parser.add_argument('--rich', action='store_true',
41 help='use a rich text frontend')
44 help='use a rich text frontend')
42 args = parser.parse_args()
45 args = parser.parse_args()
@@ -56,7 +59,10 b' def main():'
56 if args.rich:
59 if args.rich:
57 kernel_manager.start_kernel(pylab='payload-svg')
60 kernel_manager.start_kernel(pylab='payload-svg')
58 else:
61 else:
59 kernel_manager.start_kernel(pylab='qt4')
62 if args.pylab == 'auto':
63 kernel_manager.start_kernel(pylab='qt4')
64 else:
65 kernel_manager.start_kernel(pylab=args.pylab)
60 else:
66 else:
61 kernel_manager.start_kernel()
67 kernel_manager.start_kernel()
62 kernel_manager.start_channels()
68 kernel_manager.start_channels()
@@ -73,8 +73,20 b' def activate_matplotlib(backend):'
73 else:
73 else:
74 matplotlib.use(backend)
74 matplotlib.use(backend)
75 matplotlib.interactive(True)
75 matplotlib.interactive(True)
76
77 # This must be imported last in the matplotlib series, after
78 # backend/interactivity choices have been made
76 import matplotlib.pylab as pylab
79 import matplotlib.pylab as pylab
77
80
81 # XXX For now leave this commented out, but depending on discussions with
82 # mpl-dev, we may be able to allow interactive switching...
83 #import matplotlib.pyplot
84 #matplotlib.pyplot.switch_backend(backend)
85
86 pylab.show._needmain = False
87 # We need to detect at runtime whether show() is called by the user.
88 # For this, we wrap it into a decorator which adds a 'called' flag.
89 pylab.draw_if_interactive = flag_calls(pylab.draw_if_interactive)
78
90
79 def import_pylab(user_ns, import_all=True):
91 def import_pylab(user_ns, import_all=True):
80 """Import the standard pylab symbols into user_ns."""
92 """Import the standard pylab symbols into user_ns."""
@@ -115,24 +127,8 b' def pylab_activate(user_ns, gui=None, import_all=True):'
115 The actual gui used (if not given as input, it was obtained from matplotlib
127 The actual gui used (if not given as input, it was obtained from matplotlib
116 itself, and will be needed next to configure IPython's gui integration.
128 itself, and will be needed next to configure IPython's gui integration.
117 """
129 """
118
119 gui, backend = find_gui_and_backend(gui)
130 gui, backend = find_gui_and_backend(gui)
120 activate_matplotlib(backend)
131 activate_matplotlib(backend)
121
122 # This must be imported last in the matplotlib series, after
123 # backend/interactivity choices have been made
124 import matplotlib.pylab as pylab
125
126 # XXX For now leave this commented out, but depending on discussions with
127 # mpl-dev, we may be able to allow interactive switching...
128 #import matplotlib.pyplot
129 #matplotlib.pyplot.switch_backend(backend)
130
131 pylab.show._needmain = False
132 # We need to detect at runtime whether show() is called by the user.
133 # For this, we wrap it into a decorator which adds a 'called' flag.
134 pylab.draw_if_interactive = flag_calls(pylab.draw_if_interactive)
135
136 import_pylab(user_ns)
132 import_pylab(user_ns)
137
133
138 print """
134 print """
@@ -293,16 +293,79 b' class Kernel(Configurable):'
293
293
294
294
295 class QtKernel(Kernel):
295 class QtKernel(Kernel):
296 """A Kernel subclass with Qt support."""
296
297
297 def start(self):
298 def start(self):
298 """Start a kernel with QtPy4 event loop integration."""
299 """Start a kernel with QtPy4 event loop integration."""
300
299 from PyQt4 import QtGui, QtCore
301 from PyQt4 import QtGui, QtCore
300 self.qapp = app = QtGui.QApplication([])
302 self.app = QtGui.QApplication([])
301 self.qtimer = QtCore.QTimer()
303 self.app.setQuitOnLastWindowClosed (False)
302 self.qtimer.timeout.connect(self.do_one_iteration)
304 self.timer = QtCore.QTimer()
303 self.qtimer.start(50)
305 self.timer.timeout.connect(self.do_one_iteration)
304 self.qapp.exec_()
306 self.timer.start(50)
307 self.app.exec_()
308
309
310 class WxKernel(Kernel):
311 """A Kernel subclass with Wx support."""
305
312
313 def start(self):
314 """Start a kernel with wx event loop support."""
315
316 import wx
317 doi = self.do_one_iteration
318
319 # We have to put the wx.Timer in a wx.Frame for it to fire properly.
320 # We make the Frame hidden when we create it in the main app below.
321 class TimerFrame(wx.Frame):
322 def __init__(self, func):
323 wx.Frame.__init__(self, None, -1)
324 self.timer = wx.Timer(self)
325 self.timer.Start(50)
326 self.Bind(wx.EVT_TIMER, self.on_timer)
327 self.func = func
328 def on_timer(self, event):
329 self.func()
330
331 # We need a custom wx.App to create our Frame subclass that has the
332 # wx.Timer to drive the ZMQ event loop.
333 class IPWxApp(wx.App):
334 def OnInit(self):
335 self.frame = TimerFrame(doi)
336 self.frame.Show(False)
337 return True
338
339 # The redirect=False here makes sure that wx doesn't replace
340 # sys.stdout/stderr with its own classes.
341 self.app = IPWxApp(redirect=False)
342 self.app.MainLoop()
343
344
345 class TkKernel(Kernel):
346 """A Kernel subclass with Tk support."""
347
348 def start(self):
349 """Start a Tk enabled event loop."""
350
351 import Tkinter
352 doi = self.do_one_iteration
353
354 # For Tkinter, we create a Tk object and call its withdraw method.
355 class Timer(object):
356 def __init__(self, func):
357 self.app = Tkinter.Tk()
358 self.app.withdraw()
359 self.func = func
360 def on_timer(self):
361 self.func()
362 self.app.after(50, self.on_timer)
363 def start(self):
364 self.on_timer() # Call it once to get things going.
365 self.app.mainloop()
366
367 self.timer = Timer(doi)
368 self.timer.start()
306
369
307 #-----------------------------------------------------------------------------
370 #-----------------------------------------------------------------------------
308 # Kernel main and launch functions
371 # Kernel main and launch functions
@@ -365,22 +428,21 b" given, the GUI backend is matplotlib's, otherwise use one of: \\"
365 _kernel_classes = {
428 _kernel_classes = {
366 'qt' : QtKernel,
429 'qt' : QtKernel,
367 'qt4' : QtKernel,
430 'qt4' : QtKernel,
368 'payload-svg':Kernel
431 'payload-svg':Kernel,
432 'wx' : WxKernel,
433 'tk' : TkKernel
369 }
434 }
370 if namespace.pylab:
435 if namespace.pylab:
371 if namespace.pylab == 'auto':
436 if namespace.pylab == 'auto':
372 gui, backend = pylabtools.find_gui_and_backend()
437 gui, backend = pylabtools.find_gui_and_backend()
373 else:
438 else:
374 gui, backend = pylabtools.find_gui_and_backend(namespace.pylab)
439 gui, backend = pylabtools.find_gui_and_backend(namespace.pylab)
375 print gui, backend
376 kernel_class = _kernel_classes.get(gui)
440 kernel_class = _kernel_classes.get(gui)
377 if kernel_class is None:
441 if kernel_class is None:
378 raise ValueError('GUI is not supported: %r' % gui)
442 raise ValueError('GUI is not supported: %r' % gui)
379 pylabtools.activate_matplotlib(backend)
443 pylabtools.activate_matplotlib(backend)
380
444
381 print>>sys.__stdout__, kernel_class
382 kernel = make_kernel(namespace, kernel_class, OutStream)
445 kernel = make_kernel(namespace, kernel_class, OutStream)
383 print >>sys.__stdout__, kernel
384
446
385 if namespace.pylab:
447 if namespace.pylab:
386 pylabtools.import_pylab(kernel.shell.user_ns)
448 pylabtools.import_pylab(kernel.shell.user_ns)
General Comments 0
You need to be logged in to leave comments. Login now