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,36 +508,35 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.""" | |
|
515 | ||
|
516 | def loop_qt4(kernel): | |
|
517 | """Start a kernel with PyQt4 event loop integration.""" | |
|
504 | 518 | |
|
505 | 519 |
|
|
506 | 520 |
|
|
507 | 521 | |
|
508 |
|
|
|
509 |
|
|
|
510 |
|
|
|
511 |
|
|
|
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) | |
|
512 | 526 |
|
|
513 |
|
|
|
514 |
|
|
|
527 | kernel.timer.start(1000*kernel._poll_interval) | |
|
528 | start_event_loop_qt4(kernel.app) | |
|
515 | 529 | |
|
516 | 530 | |
|
517 | class WxKernel(Kernel): | |
|
518 | """A Kernel subclass with Wx support.""" | |
|
519 | ||
|
520 | def start(self): | |
|
531 | def loop_wx(kernel): | |
|
521 | 532 |
|
|
522 | 533 | |
|
523 | 534 |
|
|
524 | 535 |
|
|
525 | 536 | |
|
526 |
|
|
|
537 | doi = kernel.do_one_iteration | |
|
527 | 538 |
|
|
528 |
|
|
|
539 | poll_interval = int(1000*kernel._poll_interval) | |
|
529 | 540 | |
|
530 | 541 |
|
|
531 | 542 |
|
@@ -551,20 +562,17 b' class WxKernel(Kernel):' | |||
|
551 | 562 | |
|
552 | 563 |
|
|
553 | 564 |
|
|
554 |
|
|
|
555 |
|
|
|
556 | ||
|
565 | kernel.app = IPWxApp(redirect=False) | |
|
566 | start_event_loop_wx(kernel.app) | |
|
557 | 567 | |
|
558 | class TkKernel(Kernel): | |
|
559 | """A Kernel subclass with Tk support.""" | |
|
560 | 568 | |
|
561 | def start(self): | |
|
562 |
|
|
|
569 | def loop_tk(kernel): | |
|
570 | """Start a kernel with the Tk event loop.""" | |
|
563 | 571 | |
|
564 | 572 |
|
|
565 |
|
|
|
573 | doi = kernel.do_one_iteration | |
|
566 | 574 |
|
|
567 |
|
|
|
575 | poll_interval = int(1000*kernel._poll_interval) | |
|
568 | 576 |
|
|
569 | 577 |
|
|
570 | 578 |
|
@@ -580,43 +588,37 b' class TkKernel(Kernel):' | |||
|
580 | 588 |
|
|
581 | 589 |
|
|
582 | 590 | |
|
583 |
|
|
|
584 |
|
|
|
585 | ||
|
591 | kernel.timer = Timer(doi) | |
|
592 | kernel.timer.start() | |
|
586 | 593 | |
|
587 | class GTKKernel(Kernel): | |
|
588 | """A Kernel subclass with GTK support.""" | |
|
589 | 594 | |
|
590 | def start(self): | |
|
595 | def loop_gtk(kernel): | |
|
591 | 596 |
|
|
592 | 597 |
|
|
593 | 598 | |
|
594 |
|
|
|
599 | gtk_kernel = GTKEmbed(kernel) | |
|
595 | 600 |
|
|
596 | 601 | |
|
597 | 602 | |
|
598 | class OSXKernel(TkKernel): | |
|
599 | """A Kernel subclass with Cocoa support via the matplotlib OSX backend.""" | |
|
600 | ||
|
601 | def start(self): | |
|
603 | def loop_cocoa(kernel): | |
|
602 | 604 |
|
|
603 | 605 |
|
|
604 | 606 |
|
|
605 | 607 |
|
|
606 | 608 |
|
|
607 |
|
|
|
609 | kernel.log.warn( | |
|
608 | 610 |
|
|
609 | 611 |
|
|
610 | 612 |
|
|
611 | 613 |
|
|
612 | 614 |
|
|
613 | 615 |
|
|
614 |
|
|
|
616 | return loop_tk(kernel) | |
|
615 | 617 |
|
|
616 | 618 |
|
|
617 | 619 | |
|
618 | 620 |
|
|
619 |
|
|
|
621 | poll_interval = int(1000*kernel._poll_interval) | |
|
620 | 622 | |
|
621 | 623 |
|
|
622 | 624 |
|
@@ -630,7 +632,7 b' class OSXKernel(TkKernel):' | |||
|
630 | 632 |
|
|
631 | 633 |
|
|
632 | 634 |
|
|
633 |
|
|
|
635 | kernel.do_one_iteration() | |
|
634 | 636 |
|
|
635 | 637 |
|
|
636 | 638 | |
@@ -641,7 +643,7 b' class OSXKernel(TkKernel):' | |||
|
641 | 643 |
|
|
642 | 644 |
|
|
643 | 645 |
|
|
644 |
|
|
|
646 | poller.register(kernel.shell_socket, zmq.POLLIN) | |
|
645 | 647 | |
|
646 | 648 |
|
|
647 | 649 |
|
@@ -655,7 +657,7 b' class OSXKernel(TkKernel):' | |||
|
655 | 657 |
|
|
656 | 658 |
|
|
657 | 659 |
|
|
658 |
|
|
|
660 | kernel.do_one_iteration() | |
|
659 | 661 |
|
|
660 | 662 |
|
|
661 | 663 |
|
@@ -665,6 +667,28 b' class OSXKernel(TkKernel):' | |||
|
665 | 667 |
|
|
666 | 668 |
|
|
667 | 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 | |
|
691 | ||
|
668 | 692 | |
|
669 | 693 | #----------------------------------------------------------------------------- |
|
670 | 694 | # Aliases and Flags for the IPKernelApp |
@@ -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