Show More
@@ -289,7 +289,7 b' def import_pylab(user_ns, backend, import_all=True, shell=None):' | |||||
289 | exec s in shell.user_ns_hidden |
|
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 | """Activate pylab mode in the user's namespace. |
|
293 | """Activate pylab mode in the user's namespace. | |
294 |
|
294 | |||
295 | Loads and initializes numpy, matplotlib and friends for interactive use. |
|
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 | gui, backend = find_gui_and_backend(gui) |
|
313 | gui, backend = find_gui_and_backend(gui) | |
314 | activate_matplotlib(backend) |
|
314 | activate_matplotlib(backend) | |
315 | import_pylab(user_ns, backend, import_all) |
|
315 | import_pylab(user_ns, backend, import_all, shell) | |
316 |
|
316 | |||
317 | print """ |
|
317 | print """ | |
318 | Welcome to pylab, a matplotlib-based Python environment [backend: %s]. |
|
318 | Welcome to pylab, a matplotlib-based Python environment [backend: %s]. |
@@ -22,6 +22,7 b' import sys' | |||||
22 | import time |
|
22 | import time | |
23 | import traceback |
|
23 | import traceback | |
24 | import logging |
|
24 | import logging | |
|
25 | ||||
25 | # System library imports. |
|
26 | # System library imports. | |
26 | import zmq |
|
27 | import zmq | |
27 |
|
28 | |||
@@ -38,7 +39,7 b' from IPython.utils import py3compat' | |||||
38 | from IPython.utils.jsonutil import json_clean |
|
39 | from IPython.utils.jsonutil import json_clean | |
39 | from IPython.lib import pylabtools |
|
40 | from IPython.lib import pylabtools | |
40 | from IPython.utils.traitlets import ( |
|
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 | from entry_point import base_launch_kernel |
|
45 | from entry_point import base_launch_kernel | |
@@ -58,6 +59,9 b' class Kernel(Configurable):' | |||||
58 | # Kernel interface |
|
59 | # Kernel interface | |
59 | #--------------------------------------------------------------------------- |
|
60 | #--------------------------------------------------------------------------- | |
60 |
|
61 | |||
|
62 | # attribute to override with a GUI | |||
|
63 | eventloop = Any(None) | |||
|
64 | ||||
61 | shell = Instance('IPython.core.interactiveshell.InteractiveShellABC') |
|
65 | shell = Instance('IPython.core.interactiveshell.InteractiveShellABC') | |
62 | session = Instance(Session) |
|
66 | session = Instance(Session) | |
63 | shell_socket = Instance('zmq.Socket') |
|
67 | shell_socket = Instance('zmq.Socket') | |
@@ -164,7 +168,8 b' class Kernel(Configurable):' | |||||
164 | """ |
|
168 | """ | |
165 | poller = zmq.Poller() |
|
169 | poller = zmq.Poller() | |
166 | poller.register(self.shell_socket, zmq.POLLIN) |
|
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 | try: |
|
173 | try: | |
169 | # scale by extra factor of 10, because there is no |
|
174 | # scale by extra factor of 10, because there is no | |
170 | # reason for this to be anything less than ~ 0.1s |
|
175 | # reason for this to be anything less than ~ 0.1s | |
@@ -181,6 +186,13 b' class Kernel(Configurable):' | |||||
181 | except KeyboardInterrupt: |
|
186 | except KeyboardInterrupt: | |
182 | # Ctrl-C shouldn't crash the kernel |
|
187 | # Ctrl-C shouldn't crash the kernel | |
183 | io.raw_print("KeyboardInterrupt caught in kernel") |
|
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 | def record_ports(self, ports): |
|
197 | def record_ports(self, ports): | |
186 | """Record the ports that this kernel is using. |
|
198 | """Record the ports that this kernel is using. | |
@@ -496,174 +508,186 b' class Kernel(Configurable):' | |||||
496 | time.sleep(0.01) |
|
508 | time.sleep(0.01) | |
497 |
|
509 | |||
498 |
|
510 | |||
499 | class QtKernel(Kernel): |
|
511 | #------------------------------------------------------------------------------ | |
500 | """A Kernel subclass with Qt support.""" |
|
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 |
|
516 | def loop_qt4(kernel): | |
506 | from IPython.lib.guisupport import get_app_qt4, start_event_loop_qt4 |
|
517 | """Start a kernel with PyQt4 event loop integration.""" | |
507 |
|
518 | |||
508 | self.app = get_app_qt4([" "]) |
|
519 | from IPython.external.qt_for_kernel import QtCore | |
509 | self.app.setQuitOnLastWindowClosed(False) |
|
520 | from IPython.lib.guisupport import get_app_qt4, start_event_loop_qt4 | |
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) |
|
|||
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): |
|
531 | def loop_wx(kernel): | |
521 |
|
|
532 | """Start a kernel with wx event loop support.""" | |
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.""" |
|
|||
560 |
|
533 | |||
561 | def start(self): |
|
534 | import wx | |
562 | """Start a Tk enabled event loop.""" |
|
535 | from IPython.lib.guisupport import start_event_loop_wx | |
563 |
|
536 | |||
564 | import Tkinter |
|
537 | doi = kernel.do_one_iteration | |
565 | doi = self.do_one_iteration |
|
538 | # Wx uses milliseconds | |
566 | # Tk uses milliseconds |
|
539 | poll_interval = int(1000*kernel._poll_interval) | |
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 |
|
|||
574 |
|
540 | |||
575 | def on_timer(self): |
|
541 | # We have to put the wx.Timer in a wx.Frame for it to fire properly. | |
576 | self.func() |
|
542 | # We make the Frame hidden when we create it in the main app below. | |
577 | self.app.after(poll_interval, self.on_timer) |
|
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 |
|
|
552 | def on_timer(self, event): | |
580 | self.on_timer() # Call it once to get things going. |
|
553 | self.func() | |
581 | self.app.mainloop() |
|
|||
582 |
|
554 | |||
583 | self.timer = Timer(doi) |
|
555 | # We need a custom wx.App to create our Frame subclass that has the | |
584 | self.timer.start() |
|
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): |
|
569 | def loop_tk(kernel): | |
591 |
|
|
570 | """Start a kernel with the Tk event loop.""" | |
592 | from .gui.gtkembed import GTKEmbed |
|
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) |
|
583 | def on_timer(self): | |
595 | gtk_kernel.start() |
|
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): |
|
591 | kernel.timer = Timer(doi) | |
599 | """A Kernel subclass with Cocoa support via the matplotlib OSX backend.""" |
|
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): |
|
618 | from matplotlib.backends.backend_macosx import TimerMac, show | |
602 | """Start the kernel, coordinating with the Cocoa CFRunLoop event loop |
|
619 | ||
603 | via the matplotlib MacOSX backend. |
|
620 | # scale interval for sec->ms | |
604 | """ |
|
621 | poll_interval = int(1000*kernel._poll_interval) | |
605 | import matplotlib |
|
622 | ||
606 | if matplotlib.__version__ < '1.1.0': |
|
623 | real_excepthook = sys.excepthook | |
607 | self.log.warn( |
|
624 | def handle_int(etype, value, tb): | |
608 | "MacOSX backend in matplotlib %s doesn't have a Timer, " |
|
625 | """don't let KeyboardInterrupts look like crashes""" | |
609 | "falling back on Tk for CFRunLoop integration. Note that " |
|
626 | if etype is KeyboardInterrupt: | |
610 | "even this won't work if Tk is linked against X11 instead of " |
|
627 | io.raw_print("KeyboardInterrupt caught in CFRunLoop") | |
611 | "Cocoa (e.g. EPD). To use the MacOSX backend in the kernel, " |
|
628 | else: | |
612 | "you must use matplotlib >= 1.1.0, or a native libtk." |
|
629 | real_excepthook(etype, value, tb) | |
613 | ) |
|
630 | ||
614 | return TkKernel.start(self) |
|
631 | # add doi() as a Timer to the CFRunLoop | |
615 |
|
632 | def doi(): | ||
616 | from matplotlib.backends.backend_macosx import TimerMac, show |
|
633 | # restore excepthook during IPython code | |
617 |
|
634 | sys.excepthook = real_excepthook | ||
618 | # scale interval for sec->ms |
|
635 | kernel.do_one_iteration() | |
619 | poll_interval = int(1000*self._poll_interval) |
|
636 | # and back: | |
620 |
|
637 | sys.excepthook = handle_int | ||
621 | real_excepthook = sys.excepthook |
|
638 | ||
622 | def handle_int(etype, value, tb): |
|
639 | t = TimerMac(poll_interval) | |
623 | """don't let KeyboardInterrupts look like crashes""" |
|
640 | t.add_callback(doi) | |
624 | if etype is KeyboardInterrupt: |
|
641 | t.start() | |
625 | io.raw_print("KeyboardInterrupt caught in CFRunLoop") |
|
642 | ||
626 | else: |
|
643 | # but still need a Poller for when there are no active windows, | |
627 | real_excepthook(etype, value, tb) |
|
644 | # during which time mainloop() returns immediately | |
628 |
|
645 | poller = zmq.Poller() | ||
629 | # add doi() as a Timer to the CFRunLoop |
|
646 | poller.register(kernel.shell_socket, zmq.POLLIN) | |
630 | def doi(): |
|
647 | ||
631 | # restore excepthook during IPython code |
|
648 | while True: | |
632 | sys.excepthook = real_excepthook |
|
649 | try: | |
633 | self.do_one_iteration() |
|
650 | # double nested try/except, to properly catch KeyboardInterrupt | |
634 | # and back: |
|
651 | # due to pyzmq Issue #130 | |
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: |
|
|||
647 | try: |
|
652 | try: | |
648 | # double nested try/except, to properly catch KeyboardInterrupt |
|
653 | # don't let interrupts during mainloop invoke crash_handler: | |
649 | # due to pyzmq Issue #130 |
|
654 | sys.excepthook = handle_int | |
650 |
|
|
655 | show.mainloop() | |
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 |
|
|||
666 | sys.excepthook = real_excepthook |
|
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 | def init_kernel(self): |
|
739 | def init_kernel(self): | |
716 | kernel_factory = Kernel |
|
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 | if self.pylab: |
|
742 | if self.pylab: | |
729 | key = None if self.pylab == 'auto' else self.pylab |
|
743 | key = None if self.pylab == 'auto' else self.pylab | |
730 | gui, backend = pylabtools.find_gui_and_backend(key) |
|
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 | kernel = kernel_factory(config=self.config, session=self.session, |
|
746 | kernel = kernel_factory(config=self.config, session=self.session, | |
737 | shell_socket=self.shell_socket, |
|
747 | shell_socket=self.shell_socket, | |
738 | iopub_socket=self.iopub_socket, |
|
748 | iopub_socket=self.iopub_socket, | |
739 | stdin_socket=self.stdin_socket, |
|
749 | stdin_socket=self.stdin_socket, | |
740 | log=self.log |
|
750 | log=self.log, | |
741 | ) |
|
751 | ) | |
742 | self.kernel = kernel |
|
752 | self.kernel = kernel | |
743 | kernel.record_ports(self.ports) |
|
753 | kernel.record_ports(self.ports) | |
744 |
|
754 | |||
745 | if self.pylab: |
|
755 | if self.pylab: | |
746 |
import_all |
|
756 | kernel.shell.enable_pylab(gui, import_all=self.pylab_import_all) | |
747 | pylabtools.import_pylab(kernel.shell.user_ns, backend, import_all, |
|
|||
748 | shell=kernel.shell) |
|
|||
749 |
|
757 | |||
750 | def init_shell(self): |
|
758 | def init_shell(self): | |
751 | self.shell = self.kernel.shell |
|
759 | self.shell = self.kernel.shell |
@@ -31,6 +31,7 b' from IPython.core.displaypub import DisplayPublisher' | |||||
31 | from IPython.core.macro import Macro |
|
31 | from IPython.core.macro import Macro | |
32 | from IPython.core.magic import MacroToEdit |
|
32 | from IPython.core.magic import MacroToEdit | |
33 | from IPython.core.payloadpage import install_payload_page |
|
33 | from IPython.core.payloadpage import install_payload_page | |
|
34 | from IPython.lib import pylabtools | |||
34 | from IPython.lib.kernel import ( |
|
35 | from IPython.lib.kernel import ( | |
35 | get_connection_file, get_connection_info, connect_qtconsole |
|
36 | get_connection_file, get_connection_info, connect_qtconsole | |
36 | ) |
|
37 | ) | |
@@ -389,13 +390,65 b' class ZMQInteractiveShell(InteractiveShell):' | |||||
389 | } |
|
390 | } | |
390 | self.payload_manager.write_payload(payload) |
|
391 | self.payload_manager.write_payload(payload) | |
391 |
|
392 | |||
392 |
def magic_gui(self, |
|
393 | def magic_gui(self, parameter_s=''): | |
393 | raise NotImplementedError( |
|
394 | """Enable or disable IPython GUI event loop integration. | |
394 | 'Kernel GUI support is not implemented yet, except for --pylab.') |
|
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 | # A few magics that are adapted to the specifics of using pexpect and a |
|
453 | # A few magics that are adapted to the specifics of using pexpect and a | |
401 | # remote terminal |
|
454 | # remote terminal |
General Comments 0
You need to be logged in to leave comments.
Login now