Show More
@@ -289,7 +289,7 b' def import_pylab(user_ns, backend, import_all=True, shell=None):' | |||
|
289 | 289 | exec s in shell.user_ns_hidden |
|
290 | 290 | |
|
291 | 291 | |
|
292 | def pylab_activate(user_ns, gui=None, import_all=True): | |
|
292 | def pylab_activate(user_ns, gui=None, import_all=True, shell=None): | |
|
293 | 293 | """Activate pylab mode in the user's namespace. |
|
294 | 294 | |
|
295 | 295 | Loads and initializes numpy, matplotlib and friends for interactive use. |
@@ -312,7 +312,7 b' def pylab_activate(user_ns, gui=None, import_all=True):' | |||
|
312 | 312 | """ |
|
313 | 313 | gui, backend = find_gui_and_backend(gui) |
|
314 | 314 | activate_matplotlib(backend) |
|
315 | import_pylab(user_ns, backend, import_all) | |
|
315 | import_pylab(user_ns, backend, import_all, shell) | |
|
316 | 316 | |
|
317 | 317 | print """ |
|
318 | 318 | Welcome to pylab, a matplotlib-based Python environment [backend: %s]. |
@@ -22,6 +22,7 b' import sys' | |||
|
22 | 22 | import time |
|
23 | 23 | import traceback |
|
24 | 24 | import logging |
|
25 | ||
|
25 | 26 | # System library imports. |
|
26 | 27 | import zmq |
|
27 | 28 | |
@@ -38,7 +39,7 b' from IPython.utils import py3compat' | |||
|
38 | 39 | from IPython.utils.jsonutil import json_clean |
|
39 | 40 | from IPython.lib import pylabtools |
|
40 | 41 | from IPython.utils.traitlets import ( |
|
41 | List, Instance, Float, Dict, Bool, Int, Unicode, CaselessStrEnum | |
|
42 | Any, List, Instance, Float, Dict, Bool, Int, Unicode, CaselessStrEnum | |
|
42 | 43 | ) |
|
43 | 44 | |
|
44 | 45 | from entry_point import base_launch_kernel |
@@ -58,6 +59,9 b' class Kernel(Configurable):' | |||
|
58 | 59 | # Kernel interface |
|
59 | 60 | #--------------------------------------------------------------------------- |
|
60 | 61 | |
|
62 | # attribute to override with a GUI | |
|
63 | eventloop = Any(None) | |
|
64 | ||
|
61 | 65 | shell = Instance('IPython.core.interactiveshell.InteractiveShellABC') |
|
62 | 66 | session = Instance(Session) |
|
63 | 67 | shell_socket = Instance('zmq.Socket') |
@@ -164,7 +168,8 b' class Kernel(Configurable):' | |||
|
164 | 168 | """ |
|
165 | 169 | poller = zmq.Poller() |
|
166 | 170 | poller.register(self.shell_socket, zmq.POLLIN) |
|
167 | while True: | |
|
171 | # loop while self.eventloop has not been overridden | |
|
172 | while self.eventloop is None: | |
|
168 | 173 | try: |
|
169 | 174 | # scale by extra factor of 10, because there is no |
|
170 | 175 | # reason for this to be anything less than ~ 0.1s |
@@ -181,6 +186,13 b' class Kernel(Configurable):' | |||
|
181 | 186 | except KeyboardInterrupt: |
|
182 | 187 | # Ctrl-C shouldn't crash the kernel |
|
183 | 188 | io.raw_print("KeyboardInterrupt caught in kernel") |
|
189 | if self.eventloop is not None: | |
|
190 | try: | |
|
191 | self.eventloop(self) | |
|
192 | except KeyboardInterrupt: | |
|
193 | # Ctrl-C shouldn't crash the kernel | |
|
194 | io.raw_print("KeyboardInterrupt caught in kernel") | |
|
195 | ||
|
184 | 196 | |
|
185 | 197 | def record_ports(self, ports): |
|
186 | 198 | """Record the ports that this kernel is using. |
@@ -496,174 +508,186 b' class Kernel(Configurable):' | |||
|
496 | 508 | time.sleep(0.01) |
|
497 | 509 | |
|
498 | 510 | |
|
499 | class QtKernel(Kernel): | |
|
500 | """A Kernel subclass with Qt support.""" | |
|
511 | #------------------------------------------------------------------------------ | |
|
512 | # Eventloops for integrating the Kernel into different GUIs | |
|
513 | #------------------------------------------------------------------------------ | |
|
501 | 514 | |
|
502 | def start(self): | |
|
503 | """Start a kernel with QtPy4 event loop integration.""" | |
|
504 | 515 | |
|
505 | from IPython.external.qt_for_kernel import QtCore | |
|
506 | from IPython.lib.guisupport import get_app_qt4, start_event_loop_qt4 | |
|
516 | def loop_qt4(kernel): | |
|
517 | """Start a kernel with PyQt4 event loop integration.""" | |
|
507 | 518 | |
|
508 | self.app = get_app_qt4([" "]) | |
|
509 | self.app.setQuitOnLastWindowClosed(False) | |
|
510 | self.timer = QtCore.QTimer() | |
|
511 | self.timer.timeout.connect(self.do_one_iteration) | |
|
512 | # Units for the timer are in milliseconds | |
|
513 | self.timer.start(1000*self._poll_interval) | |
|
514 | start_event_loop_qt4(self.app) | |
|
519 | from IPython.external.qt_for_kernel import QtCore | |
|
520 | from IPython.lib.guisupport import get_app_qt4, start_event_loop_qt4 | |
|
515 | 521 | |
|
522 | kernel.app = get_app_qt4([" "]) | |
|
523 | kernel.app.setQuitOnLastWindowClosed(False) | |
|
524 | kernel.timer = QtCore.QTimer() | |
|
525 | kernel.timer.timeout.connect(kernel.do_one_iteration) | |
|
526 | # Units for the timer are in milliseconds | |
|
527 | kernel.timer.start(1000*kernel._poll_interval) | |
|
528 | start_event_loop_qt4(kernel.app) | |
|
516 | 529 | |
|
517 | class WxKernel(Kernel): | |
|
518 | """A Kernel subclass with Wx support.""" | |
|
519 | 530 | |
|
520 | def start(self): | |
|
521 |
|
|
|
522 | ||
|
523 | import wx | |
|
524 | from IPython.lib.guisupport import start_event_loop_wx | |
|
525 | ||
|
526 | doi = self.do_one_iteration | |
|
527 | # Wx uses milliseconds | |
|
528 | poll_interval = int(1000*self._poll_interval) | |
|
529 | ||
|
530 | # We have to put the wx.Timer in a wx.Frame for it to fire properly. | |
|
531 | # We make the Frame hidden when we create it in the main app below. | |
|
532 | class TimerFrame(wx.Frame): | |
|
533 | def __init__(self, func): | |
|
534 | wx.Frame.__init__(self, None, -1) | |
|
535 | self.timer = wx.Timer(self) | |
|
536 | # Units for the timer are in milliseconds | |
|
537 | self.timer.Start(poll_interval) | |
|
538 | self.Bind(wx.EVT_TIMER, self.on_timer) | |
|
539 | self.func = func | |
|
540 | ||
|
541 | def on_timer(self, event): | |
|
542 | self.func() | |
|
543 | ||
|
544 | # We need a custom wx.App to create our Frame subclass that has the | |
|
545 | # wx.Timer to drive the ZMQ event loop. | |
|
546 | class IPWxApp(wx.App): | |
|
547 | def OnInit(self): | |
|
548 | self.frame = TimerFrame(doi) | |
|
549 | self.frame.Show(False) | |
|
550 | return True | |
|
551 | ||
|
552 | # The redirect=False here makes sure that wx doesn't replace | |
|
553 | # sys.stdout/stderr with its own classes. | |
|
554 | self.app = IPWxApp(redirect=False) | |
|
555 | start_event_loop_wx(self.app) | |
|
556 | ||
|
557 | ||
|
558 | class TkKernel(Kernel): | |
|
559 | """A Kernel subclass with Tk support.""" | |
|
531 | def loop_wx(kernel): | |
|
532 | """Start a kernel with wx event loop support.""" | |
|
560 | 533 | |
|
561 | def start(self): | |
|
562 | """Start a Tk enabled event loop.""" | |
|
534 | import wx | |
|
535 | from IPython.lib.guisupport import start_event_loop_wx | |
|
563 | 536 | |
|
564 | import Tkinter | |
|
565 | doi = self.do_one_iteration | |
|
566 | # Tk uses milliseconds | |
|
567 | poll_interval = int(1000*self._poll_interval) | |
|
568 | # For Tkinter, we create a Tk object and call its withdraw method. | |
|
569 | class Timer(object): | |
|
570 | def __init__(self, func): | |
|
571 | self.app = Tkinter.Tk() | |
|
572 | self.app.withdraw() | |
|
573 | self.func = func | |
|
537 | doi = kernel.do_one_iteration | |
|
538 | # Wx uses milliseconds | |
|
539 | poll_interval = int(1000*kernel._poll_interval) | |
|
574 | 540 | |
|
575 | def on_timer(self): | |
|
576 | self.func() | |
|
577 | self.app.after(poll_interval, self.on_timer) | |
|
541 | # We have to put the wx.Timer in a wx.Frame for it to fire properly. | |
|
542 | # We make the Frame hidden when we create it in the main app below. | |
|
543 | class TimerFrame(wx.Frame): | |
|
544 | def __init__(self, func): | |
|
545 | wx.Frame.__init__(self, None, -1) | |
|
546 | self.timer = wx.Timer(self) | |
|
547 | # Units for the timer are in milliseconds | |
|
548 | self.timer.Start(poll_interval) | |
|
549 | self.Bind(wx.EVT_TIMER, self.on_timer) | |
|
550 | self.func = func | |
|
578 | 551 | |
|
579 |
|
|
|
580 | self.on_timer() # Call it once to get things going. | |
|
581 | self.app.mainloop() | |
|
552 | def on_timer(self, event): | |
|
553 | self.func() | |
|
582 | 554 | |
|
583 | self.timer = Timer(doi) | |
|
584 | self.timer.start() | |
|
555 | # We need a custom wx.App to create our Frame subclass that has the | |
|
556 | # wx.Timer to drive the ZMQ event loop. | |
|
557 | class IPWxApp(wx.App): | |
|
558 | def OnInit(self): | |
|
559 | self.frame = TimerFrame(doi) | |
|
560 | self.frame.Show(False) | |
|
561 | return True | |
|
585 | 562 | |
|
563 | # The redirect=False here makes sure that wx doesn't replace | |
|
564 | # sys.stdout/stderr with its own classes. | |
|
565 | kernel.app = IPWxApp(redirect=False) | |
|
566 | start_event_loop_wx(kernel.app) | |
|
586 | 567 | |
|
587 | class GTKKernel(Kernel): | |
|
588 | """A Kernel subclass with GTK support.""" | |
|
589 | 568 | |
|
590 | def start(self): | |
|
591 |
|
|
|
592 | from .gui.gtkembed import GTKEmbed | |
|
569 | def loop_tk(kernel): | |
|
570 | """Start a kernel with the Tk event loop.""" | |
|
571 | ||
|
572 | import Tkinter | |
|
573 | doi = kernel.do_one_iteration | |
|
574 | # Tk uses milliseconds | |
|
575 | poll_interval = int(1000*kernel._poll_interval) | |
|
576 | # For Tkinter, we create a Tk object and call its withdraw method. | |
|
577 | class Timer(object): | |
|
578 | def __init__(self, func): | |
|
579 | self.app = Tkinter.Tk() | |
|
580 | self.app.withdraw() | |
|
581 | self.func = func | |
|
593 | 582 | |
|
594 | gtk_kernel = GTKEmbed(self) | |
|
595 | gtk_kernel.start() | |
|
583 | def on_timer(self): | |
|
584 | self.func() | |
|
585 | self.app.after(poll_interval, self.on_timer) | |
|
596 | 586 | |
|
587 | def start(self): | |
|
588 | self.on_timer() # Call it once to get things going. | |
|
589 | self.app.mainloop() | |
|
597 | 590 | |
|
598 | class OSXKernel(TkKernel): | |
|
599 | """A Kernel subclass with Cocoa support via the matplotlib OSX backend.""" | |
|
591 | kernel.timer = Timer(doi) | |
|
592 | kernel.timer.start() | |
|
593 | ||
|
594 | ||
|
595 | def loop_gtk(kernel): | |
|
596 | """Start the kernel, coordinating with the GTK event loop""" | |
|
597 | from .gui.gtkembed import GTKEmbed | |
|
598 | ||
|
599 | gtk_kernel = GTKEmbed(kernel) | |
|
600 | gtk_kernel.start() | |
|
601 | ||
|
602 | ||
|
603 | def loop_cocoa(kernel): | |
|
604 | """Start the kernel, coordinating with the Cocoa CFRunLoop event loop | |
|
605 | via the matplotlib MacOSX backend. | |
|
606 | """ | |
|
607 | import matplotlib | |
|
608 | if matplotlib.__version__ < '1.1.0': | |
|
609 | kernel.log.warn( | |
|
610 | "MacOSX backend in matplotlib %s doesn't have a Timer, " | |
|
611 | "falling back on Tk for CFRunLoop integration. Note that " | |
|
612 | "even this won't work if Tk is linked against X11 instead of " | |
|
613 | "Cocoa (e.g. EPD). To use the MacOSX backend in the kernel, " | |
|
614 | "you must use matplotlib >= 1.1.0, or a native libtk." | |
|
615 | ) | |
|
616 | return loop_tk(kernel) | |
|
600 | 617 | |
|
601 | def start(self): | |
|
602 | """Start the kernel, coordinating with the Cocoa CFRunLoop event loop | |
|
603 | via the matplotlib MacOSX backend. | |
|
604 | """ | |
|
605 | import matplotlib | |
|
606 | if matplotlib.__version__ < '1.1.0': | |
|
607 | self.log.warn( | |
|
608 | "MacOSX backend in matplotlib %s doesn't have a Timer, " | |
|
609 | "falling back on Tk for CFRunLoop integration. Note that " | |
|
610 | "even this won't work if Tk is linked against X11 instead of " | |
|
611 | "Cocoa (e.g. EPD). To use the MacOSX backend in the kernel, " | |
|
612 | "you must use matplotlib >= 1.1.0, or a native libtk." | |
|
613 | ) | |
|
614 | return TkKernel.start(self) | |
|
615 | ||
|
616 | from matplotlib.backends.backend_macosx import TimerMac, show | |
|
617 | ||
|
618 | # scale interval for sec->ms | |
|
619 | poll_interval = int(1000*self._poll_interval) | |
|
620 | ||
|
621 | real_excepthook = sys.excepthook | |
|
622 | def handle_int(etype, value, tb): | |
|
623 | """don't let KeyboardInterrupts look like crashes""" | |
|
624 | if etype is KeyboardInterrupt: | |
|
625 | io.raw_print("KeyboardInterrupt caught in CFRunLoop") | |
|
626 | else: | |
|
627 | real_excepthook(etype, value, tb) | |
|
628 | ||
|
629 | # add doi() as a Timer to the CFRunLoop | |
|
630 | def doi(): | |
|
631 | # restore excepthook during IPython code | |
|
632 | sys.excepthook = real_excepthook | |
|
633 | self.do_one_iteration() | |
|
634 | # and back: | |
|
635 | sys.excepthook = handle_int | |
|
636 | ||
|
637 | t = TimerMac(poll_interval) | |
|
638 | t.add_callback(doi) | |
|
639 | t.start() | |
|
640 | ||
|
641 | # but still need a Poller for when there are no active windows, | |
|
642 | # during which time mainloop() returns immediately | |
|
643 | poller = zmq.Poller() | |
|
644 | poller.register(self.shell_socket, zmq.POLLIN) | |
|
645 | ||
|
646 | while True: | |
|
618 | from matplotlib.backends.backend_macosx import TimerMac, show | |
|
619 | ||
|
620 | # scale interval for sec->ms | |
|
621 | poll_interval = int(1000*kernel._poll_interval) | |
|
622 | ||
|
623 | real_excepthook = sys.excepthook | |
|
624 | def handle_int(etype, value, tb): | |
|
625 | """don't let KeyboardInterrupts look like crashes""" | |
|
626 | if etype is KeyboardInterrupt: | |
|
627 | io.raw_print("KeyboardInterrupt caught in CFRunLoop") | |
|
628 | else: | |
|
629 | real_excepthook(etype, value, tb) | |
|
630 | ||
|
631 | # add doi() as a Timer to the CFRunLoop | |
|
632 | def doi(): | |
|
633 | # restore excepthook during IPython code | |
|
634 | sys.excepthook = real_excepthook | |
|
635 | kernel.do_one_iteration() | |
|
636 | # and back: | |
|
637 | sys.excepthook = handle_int | |
|
638 | ||
|
639 | t = TimerMac(poll_interval) | |
|
640 | t.add_callback(doi) | |
|
641 | t.start() | |
|
642 | ||
|
643 | # but still need a Poller for when there are no active windows, | |
|
644 | # during which time mainloop() returns immediately | |
|
645 | poller = zmq.Poller() | |
|
646 | poller.register(kernel.shell_socket, zmq.POLLIN) | |
|
647 | ||
|
648 | while True: | |
|
649 | try: | |
|
650 | # double nested try/except, to properly catch KeyboardInterrupt | |
|
651 | # due to pyzmq Issue #130 | |
|
647 | 652 | try: |
|
648 | # double nested try/except, to properly catch KeyboardInterrupt | |
|
649 | # due to pyzmq Issue #130 | |
|
650 |
|
|
|
651 | # don't let interrupts during mainloop invoke crash_handler: | |
|
652 | sys.excepthook = handle_int | |
|
653 | show.mainloop() | |
|
654 | sys.excepthook = real_excepthook | |
|
655 | # use poller if mainloop returned (no windows) | |
|
656 | # scale by extra factor of 10, since it's a real poll | |
|
657 | poller.poll(10*poll_interval) | |
|
658 | self.do_one_iteration() | |
|
659 | except: | |
|
660 | raise | |
|
661 | except KeyboardInterrupt: | |
|
662 | # Ctrl-C shouldn't crash the kernel | |
|
663 | io.raw_print("KeyboardInterrupt caught in kernel") | |
|
664 | finally: | |
|
665 | # ensure excepthook is restored | |
|
653 | # don't let interrupts during mainloop invoke crash_handler: | |
|
654 | sys.excepthook = handle_int | |
|
655 | show.mainloop() | |
|
666 | 656 | sys.excepthook = real_excepthook |
|
657 | # use poller if mainloop returned (no windows) | |
|
658 | # scale by extra factor of 10, since it's a real poll | |
|
659 | poller.poll(10*poll_interval) | |
|
660 | kernel.do_one_iteration() | |
|
661 | except: | |
|
662 | raise | |
|
663 | except KeyboardInterrupt: | |
|
664 | # Ctrl-C shouldn't crash the kernel | |
|
665 | io.raw_print("KeyboardInterrupt caught in kernel") | |
|
666 | finally: | |
|
667 | # ensure excepthook is restored | |
|
668 | sys.excepthook = real_excepthook | |
|
669 | ||
|
670 | # mapping of keys to loop functions | |
|
671 | loop_map = { | |
|
672 | 'qt' : loop_qt4, | |
|
673 | 'qt4': loop_qt4, | |
|
674 | 'inline': None, | |
|
675 | 'osx': loop_cocoa, | |
|
676 | 'wx' : loop_wx, | |
|
677 | 'tk' : loop_tk, | |
|
678 | 'gtk': loop_gtk, | |
|
679 | } | |
|
680 | ||
|
681 | def enable_gui(gui, kernel=None): | |
|
682 | """Enable integration with a give GUI""" | |
|
683 | if kernel is None: | |
|
684 | kernel = IPKernelApp.instance().kernel | |
|
685 | if gui not in loop_map: | |
|
686 | raise ValueError("GUI %r not supported" % gui) | |
|
687 | loop = loop_map[gui] | |
|
688 | if kernel.eventloop is not None and kernel.eventloop is not loop: | |
|
689 | raise RuntimeError("Cannot activate multiple GUI eventloops") | |
|
690 | kernel.eventloop = loop | |
|
667 | 691 | |
|
668 | 692 | |
|
669 | 693 | #----------------------------------------------------------------------------- |
@@ -715,37 +739,21 b' class IPKernelApp(KernelApp, InteractiveShellApp):' | |||
|
715 | 739 | def init_kernel(self): |
|
716 | 740 | kernel_factory = Kernel |
|
717 | 741 | |
|
718 | kernel_map = { | |
|
719 | 'qt' : QtKernel, | |
|
720 | 'qt4': QtKernel, | |
|
721 | 'inline': Kernel, | |
|
722 | 'osx': OSXKernel, | |
|
723 | 'wx' : WxKernel, | |
|
724 | 'tk' : TkKernel, | |
|
725 | 'gtk': GTKKernel, | |
|
726 | } | |
|
727 | ||
|
728 | 742 | if self.pylab: |
|
729 | 743 | key = None if self.pylab == 'auto' else self.pylab |
|
730 | 744 | gui, backend = pylabtools.find_gui_and_backend(key) |
|
731 | kernel_factory = kernel_map.get(gui) | |
|
732 | if kernel_factory is None: | |
|
733 | raise ValueError('GUI is not supported: %r' % gui) | |
|
734 | pylabtools.activate_matplotlib(backend) | |
|
735 | 745 | |
|
736 | 746 | kernel = kernel_factory(config=self.config, session=self.session, |
|
737 | 747 | shell_socket=self.shell_socket, |
|
738 | 748 | iopub_socket=self.iopub_socket, |
|
739 | 749 | stdin_socket=self.stdin_socket, |
|
740 | log=self.log | |
|
750 | log=self.log, | |
|
741 | 751 | ) |
|
742 | 752 | self.kernel = kernel |
|
743 | 753 | kernel.record_ports(self.ports) |
|
744 | 754 | |
|
745 | 755 | if self.pylab: |
|
746 |
import_all |
|
|
747 | pylabtools.import_pylab(kernel.shell.user_ns, backend, import_all, | |
|
748 | shell=kernel.shell) | |
|
756 | kernel.shell.enable_pylab(gui, import_all=self.pylab_import_all) | |
|
749 | 757 | |
|
750 | 758 | def init_shell(self): |
|
751 | 759 | self.shell = self.kernel.shell |
@@ -31,6 +31,7 b' from IPython.core.displaypub import DisplayPublisher' | |||
|
31 | 31 | from IPython.core.macro import Macro |
|
32 | 32 | from IPython.core.magic import MacroToEdit |
|
33 | 33 | from IPython.core.payloadpage import install_payload_page |
|
34 | from IPython.lib import pylabtools | |
|
34 | 35 | from IPython.lib.kernel import ( |
|
35 | 36 | get_connection_file, get_connection_info, connect_qtconsole |
|
36 | 37 | ) |
@@ -389,13 +390,65 b' class ZMQInteractiveShell(InteractiveShell):' | |||
|
389 | 390 | } |
|
390 | 391 | self.payload_manager.write_payload(payload) |
|
391 | 392 | |
|
392 |
def magic_gui(self, |
|
|
393 | raise NotImplementedError( | |
|
394 | 'Kernel GUI support is not implemented yet, except for --pylab.') | |
|
393 | def magic_gui(self, parameter_s=''): | |
|
394 | """Enable or disable IPython GUI event loop integration. | |
|
395 | ||
|
396 | %gui [GUINAME] | |
|
397 | ||
|
398 | This magic replaces IPython's threaded shells that were activated | |
|
399 | using the (pylab/wthread/etc.) command line flags. GUI toolkits | |
|
400 | can now be enabled at runtime and keyboard | |
|
401 | interrupts should work without any problems. The following toolkits | |
|
402 | are supported: wxPython, PyQt4, PyGTK, Cocoa, and Tk:: | |
|
403 | ||
|
404 | %gui wx # enable wxPython event loop integration | |
|
405 | %gui qt4|qt # enable PyQt4 event loop integration | |
|
406 | %gui gtk # enable PyGTK event loop integration | |
|
407 | %gui OSX # enable Cocoa event loop integration (requires matplotlib 1.1) | |
|
408 | %gui tk # enable Tk event loop integration | |
|
409 | ||
|
410 | WARNING: after any of these has been called you can simply create | |
|
411 | an application object, but DO NOT start the event loop yourself, as | |
|
412 | we have already handled that. | |
|
413 | """ | |
|
414 | from IPython.zmq.ipkernel import enable_gui | |
|
415 | opts, arg = self.parse_options(parameter_s, '') | |
|
416 | if arg=='': arg = None | |
|
417 | return enable_gui(arg) | |
|
418 | ||
|
419 | def enable_pylab(self, gui=None, import_all=True): | |
|
420 | """Activate pylab support at runtime. | |
|
421 | ||
|
422 | This turns on support for matplotlib, preloads into the interactive | |
|
423 | namespace all of numpy and pylab, and configures IPython to correcdtly | |
|
424 | interact with the GUI event loop. The GUI backend to be used can be | |
|
425 | optionally selected with the optional :param:`gui` argument. | |
|
426 | ||
|
427 | Parameters | |
|
428 | ---------- | |
|
429 | gui : optional, string [default: inline] | |
|
430 | ||
|
431 | If given, dictates the choice of matplotlib GUI backend to use | |
|
432 | (should be one of IPython's supported backends, 'inline', 'qt', 'osx', | |
|
433 | 'tk', or 'gtk'), otherwise we use the default chosen by matplotlib | |
|
434 | (as dictated by the matplotlib build-time options plus the user's | |
|
435 | matplotlibrc configuration file). | |
|
436 | """ | |
|
437 | from IPython.zmq.ipkernel import enable_gui | |
|
438 | # We want to prevent the loading of pylab to pollute the user's | |
|
439 | # namespace as shown by the %who* magics, so we execute the activation | |
|
440 | # code in an empty namespace, and we update *both* user_ns and | |
|
441 | # user_ns_hidden with this information. | |
|
442 | ns = {} | |
|
443 | # override default to inline, from auto-detect | |
|
444 | gui = pylabtools.pylab_activate(ns, gui or 'inline', import_all, self) | |
|
445 | self.user_ns.update(ns) | |
|
446 | self.user_ns_hidden.update(ns) | |
|
447 | # Now we must activate the gui pylab wants to use, and fix %run to take | |
|
448 | # plot updates into account | |
|
449 | enable_gui(gui) | |
|
450 | self.magic_run = self._pylab_magic_run | |
|
395 | 451 | |
|
396 | def magic_pylab(self, *args, **kwargs): | |
|
397 | raise NotImplementedError( | |
|
398 | 'pylab support must be enabled in command line options.') | |
|
399 | 452 | |
|
400 | 453 | # A few magics that are adapted to the specifics of using pexpect and a |
|
401 | 454 | # remote terminal |
General Comments 0
You need to be logged in to leave comments.
Login now