Show More
@@ -194,8 +194,8 b' class InteractiveShell(Configurable, Magic):' | |||||
194 | # TODO: this part of prompt management should be moved to the frontends. |
|
194 | # TODO: this part of prompt management should be moved to the frontends. | |
195 | # Use custom TraitTypes that convert '0'->'' and '\\n'->'\n' |
|
195 | # Use custom TraitTypes that convert '0'->'' and '\\n'->'\n' | |
196 | separate_in = SeparateStr('\n', config=True) |
|
196 | separate_in = SeparateStr('\n', config=True) | |
197 |
separate_out = SeparateStr(' |
|
197 | separate_out = SeparateStr('', config=True) | |
198 |
separate_out2 = SeparateStr(' |
|
198 | separate_out2 = SeparateStr('', config=True) | |
199 | system_header = Str('IPython system call: ', config=True) |
|
199 | system_header = Str('IPython system call: ', config=True) | |
200 | system_verbose = CBool(False, config=True) |
|
200 | system_verbose = CBool(False, config=True) | |
201 | wildcards_case_sensitive = CBool(True, config=True) |
|
201 | wildcards_case_sensitive = CBool(True, config=True) |
@@ -604,7 +604,7 b' class ListTB(TBTools):' | |||||
604 | return ListTB.structured_traceback(self, etype, value, []) |
|
604 | return ListTB.structured_traceback(self, etype, value, []) | |
605 |
|
605 | |||
606 |
|
606 | |||
607 | def show_exception_only(self, etype, value): |
|
607 | def show_exception_only(self, etype, evalue): | |
608 | """Only print the exception type and message, without a traceback. |
|
608 | """Only print the exception type and message, without a traceback. | |
609 |
|
609 | |||
610 | Parameters |
|
610 | Parameters |
@@ -5,7 +5,6 b' import sys' | |||||
5 | # System library imports |
|
5 | # System library imports | |
6 | from pygments.lexers import PythonLexer |
|
6 | from pygments.lexers import PythonLexer | |
7 | from PyQt4 import QtCore, QtGui |
|
7 | from PyQt4 import QtCore, QtGui | |
8 | import zmq |
|
|||
9 |
|
8 | |||
10 | # Local imports |
|
9 | # Local imports | |
11 | from IPython.core.inputsplitter import InputSplitter |
|
10 | from IPython.core.inputsplitter import InputSplitter |
@@ -4,7 +4,7 b'' | |||||
4 | """ |
|
4 | """ | |
5 |
|
5 | |||
6 | # Systemm library imports |
|
6 | # Systemm library imports | |
7 |
from PyQt4 import |
|
7 | from PyQt4 import QtGui | |
8 |
|
8 | |||
9 | # Local imports |
|
9 | # Local imports | |
10 | from IPython.external.argparse import ArgumentParser |
|
10 | from IPython.external.argparse import ArgumentParser | |
@@ -37,8 +37,11 b' def main():' | |||||
37 | egroup = kgroup.add_mutually_exclusive_group() |
|
37 | egroup = kgroup.add_mutually_exclusive_group() | |
38 | egroup.add_argument('--pure', action='store_true', help = \ |
|
38 | egroup.add_argument('--pure', action='store_true', help = \ | |
39 | 'use a pure Python kernel instead of an IPython kernel') |
|
39 | 'use a pure Python kernel instead of an IPython kernel') | |
40 |
egroup.add_argument('--pylab', |
|
40 | egroup.add_argument('--pylab', type=str, metavar='GUI', nargs='?', | |
41 | help='use a kernel with PyLab enabled') |
|
41 | const='auto', help = \ | |
|
42 | "Pre-load matplotlib and numpy for interactive use. If GUI is not \ | |||
|
43 | given, the GUI backend is matplotlib's, otherwise use one of: \ | |||
|
44 | ['tk', 'gtk', 'qt', 'wx', 'payload-svg'].") | |||
42 |
|
45 | |||
43 | wgroup = parser.add_argument_group('widget options') |
|
46 | wgroup = parser.add_argument_group('widget options') | |
44 | wgroup.add_argument('--paging', type=str, default='inside', |
|
47 | wgroup.add_argument('--paging', type=str, default='inside', | |
@@ -48,9 +51,9 b' def main():' | |||||
48 | help='enable rich text support') |
|
51 | help='enable rich text support') | |
49 | wgroup.add_argument('--tab-simple', action='store_true', |
|
52 | wgroup.add_argument('--tab-simple', action='store_true', | |
50 | help='do tab completion ala a Unix terminal') |
|
53 | help='do tab completion ala a Unix terminal') | |
51 |
|
54 | |||
52 | args = parser.parse_args() |
|
55 | args = parser.parse_args() | |
53 |
|
56 | |||
54 | # Don't let Qt or ZMQ swallow KeyboardInterupts. |
|
57 | # Don't let Qt or ZMQ swallow KeyboardInterupts. | |
55 | import signal |
|
58 | import signal | |
56 | signal.signal(signal.SIGINT, signal.SIG_DFL) |
|
59 | signal.signal(signal.SIGINT, signal.SIG_DFL) | |
@@ -66,7 +69,10 b' def main():' | |||||
66 | if args.rich: |
|
69 | if args.rich: | |
67 | kernel_manager.start_kernel(pylab='payload-svg') |
|
70 | kernel_manager.start_kernel(pylab='payload-svg') | |
68 | else: |
|
71 | else: | |
69 | kernel_manager.start_kernel(pylab='qt4') |
|
72 | if args.pylab == 'auto': | |
|
73 | kernel_manager.start_kernel(pylab='qt4') | |||
|
74 | else: | |||
|
75 | kernel_manager.start_kernel(pylab=args.pylab) | |||
70 | else: |
|
76 | else: | |
71 | kernel_manager.start_kernel() |
|
77 | kernel_manager.start_kernel() | |
72 | kernel_manager.start_channels() |
|
78 | kernel_manager.start_channels() |
@@ -76,7 +76,7 b' def appstart_qt4(app):' | |||||
76 | except ImportError: |
|
76 | except ImportError: | |
77 | app.exec_() |
|
77 | app.exec_() | |
78 | """ |
|
78 | """ | |
79 |
from PyQt4 import QtCore |
|
79 | from PyQt4 import QtCore | |
80 |
|
80 | |||
81 | assert isinstance(app, QtCore.QCoreApplication) |
|
81 | assert isinstance(app, QtCore.QCoreApplication) | |
82 | if app is not None: |
|
82 | if app is not None: | |
@@ -241,6 +241,7 b' class InputHookManager(object):' | |||||
241 | mainloop at anytime but startup. |
|
241 | mainloop at anytime but startup. | |
242 | """ |
|
242 | """ | |
243 | import Tkinter |
|
243 | import Tkinter | |
|
244 | # FIXME: gtk is not imported here and we shouldn't be using gtk.main! | |||
244 | orig_mainloop = gtk.main |
|
245 | orig_mainloop = gtk.main | |
245 | dumb_ml = _DummyMainloop(orig_mainloop, self, GUI_TK) |
|
246 | dumb_ml = _DummyMainloop(orig_mainloop, self, GUI_TK) | |
246 | Tkinter.Misc.mainloop = dumb_ml |
|
247 | Tkinter.Misc.mainloop = dumb_ml | |
@@ -252,7 +253,7 b' class InputHookManager(object):' | |||||
252 | This is for internal IPython use only and user code should not call this. |
|
253 | This is for internal IPython use only and user code should not call this. | |
253 | Instead, they should issue the raw GUI calls themselves. |
|
254 | Instead, they should issue the raw GUI calls themselves. | |
254 | """ |
|
255 | """ | |
255 |
from PyQt4 import QtCore |
|
256 | from PyQt4 import QtCore | |
256 |
|
257 | |||
257 | app = QtCore.QCoreApplication.instance() |
|
258 | app = QtCore.QCoreApplication.instance() | |
258 | if app is not None: |
|
259 | if app is not None: |
@@ -23,29 +23,21 b' from IPython.utils.decorators import flag_calls' | |||||
23 | # Main classes and functions |
|
23 | # Main classes and functions | |
24 | #----------------------------------------------------------------------------- |
|
24 | #----------------------------------------------------------------------------- | |
25 |
|
25 | |||
26 | def pylab_activate(user_ns, gui=None, import_all=True): |
|
|||
27 | """Activate pylab mode in the user's namespace. |
|
|||
28 |
|
26 | |||
29 | Loads and initializes numpy, matplotlib and friends for interactive use. |
|
27 | def find_gui_and_backend(gui=None): | |
|
28 | """Given a gui string return the gui and mpl backend. | |||
30 |
|
29 | |||
31 | Parameters |
|
30 | Parameters | |
32 | ---------- |
|
31 | ---------- | |
33 | user_ns : dict |
|
32 | gui : str | |
34 | Namespace where the imports will occur. |
|
33 | Can be one of ('tk','gtk','wx','qt','qt4','payload-svg'). | |
35 |
|
||||
36 | gui : optional, string |
|
|||
37 | A valid gui name following the conventions of the %gui magic. |
|
|||
38 |
|
||||
39 | import_all : optional, boolean |
|
|||
40 | If true, an 'import *' is done from numpy and pylab. |
|
|||
41 |
|
34 | |||
42 | Returns |
|
35 | Returns | |
43 | ------- |
|
36 | ------- | |
44 | The actual gui used (if not given as input, it was obtained from matplotlib |
|
37 | A tuple of (gui, backend) where backend is one of ('TkAgg','GTKAgg', | |
45 | itself, and will be needed next to configure IPython's gui integration. |
|
38 | 'WXAgg','Qt4Agg','module://IPython.zmq.pylab.backend_payload_svg'). | |
46 | """ |
|
39 | """ | |
47 |
|
40 | |||
48 | # Initialize matplotlib to interactive mode always |
|
|||
49 | import matplotlib |
|
41 | import matplotlib | |
50 |
|
42 | |||
51 | # If user specifies a GUI, that dictates the backend, otherwise we read the |
|
43 | # If user specifies a GUI, that dictates the backend, otherwise we read the | |
@@ -54,7 +46,9 b' def pylab_activate(user_ns, gui=None, import_all=True):' | |||||
54 | 'gtk': 'GTKAgg', |
|
46 | 'gtk': 'GTKAgg', | |
55 | 'wx': 'WXAgg', |
|
47 | 'wx': 'WXAgg', | |
56 | 'qt': 'Qt4Agg', # qt3 not supported |
|
48 | 'qt': 'Qt4Agg', # qt3 not supported | |
57 |
'qt4': 'Qt4Agg' |
|
49 | 'qt4': 'Qt4Agg', | |
|
50 | 'payload-svg' : \ | |||
|
51 | 'module://IPython.zmq.pylab.backend_payload_svg'} | |||
58 |
|
52 | |||
59 | if gui: |
|
53 | if gui: | |
60 | # select backend based on requested gui |
|
54 | # select backend based on requested gui | |
@@ -65,10 +59,21 b' def pylab_activate(user_ns, gui=None, import_all=True):' | |||||
65 | # should be for IPython, so we can activate inputhook accordingly |
|
59 | # should be for IPython, so we can activate inputhook accordingly | |
66 | b2g = dict(zip(g2b.values(),g2b.keys())) |
|
60 | b2g = dict(zip(g2b.values(),g2b.keys())) | |
67 | gui = b2g.get(backend, None) |
|
61 | gui = b2g.get(backend, None) | |
|
62 | return gui, backend | |||
|
63 | ||||
|
64 | ||||
|
65 | def activate_matplotlib(backend): | |||
|
66 | """Activate the given backend and set interactive to True.""" | |||
|
67 | ||||
|
68 | import matplotlib | |||
|
69 | if backend.startswith('module://'): | |||
|
70 | # Work around bug in matplotlib: matplotlib.use converts the | |||
|
71 | # backend_id to lowercase even if a module name is specified! | |||
|
72 | matplotlib.rcParams['backend'] = backend | |||
|
73 | else: | |||
|
74 | matplotlib.use(backend) | |||
|
75 | matplotlib.interactive(True) | |||
68 |
|
76 | |||
69 | # We must set the desired backend before importing pylab |
|
|||
70 | matplotlib.use(backend) |
|
|||
71 |
|
||||
72 | # This must be imported last in the matplotlib series, after |
|
77 | # This must be imported last in the matplotlib series, after | |
73 | # backend/interactivity choices have been made |
|
78 | # backend/interactivity choices have been made | |
74 | import matplotlib.pylab as pylab |
|
79 | import matplotlib.pylab as pylab | |
@@ -83,6 +88,9 b' def pylab_activate(user_ns, gui=None, import_all=True):' | |||||
83 | # For this, we wrap it into a decorator which adds a 'called' flag. |
|
88 | # For this, we wrap it into a decorator which adds a 'called' flag. | |
84 | pylab.draw_if_interactive = flag_calls(pylab.draw_if_interactive) |
|
89 | pylab.draw_if_interactive = flag_calls(pylab.draw_if_interactive) | |
85 |
|
90 | |||
|
91 | def import_pylab(user_ns, import_all=True): | |||
|
92 | """Import the standard pylab symbols into user_ns.""" | |||
|
93 | ||||
86 | # Import numpy as np/pyplot as plt are conventions we're trying to |
|
94 | # Import numpy as np/pyplot as plt are conventions we're trying to | |
87 | # somewhat standardize on. Making them available to users by default |
|
95 | # somewhat standardize on. Making them available to users by default | |
88 | # will greatly help this. |
|
96 | # will greatly help this. | |
@@ -97,7 +105,31 b' def pylab_activate(user_ns, gui=None, import_all=True):' | |||||
97 | exec("from matplotlib.pylab import *\n" |
|
105 | exec("from matplotlib.pylab import *\n" | |
98 | "from numpy import *\n") in user_ns |
|
106 | "from numpy import *\n") in user_ns | |
99 |
|
107 | |||
100 | matplotlib.interactive(True) |
|
108 | ||
|
109 | def pylab_activate(user_ns, gui=None, import_all=True): | |||
|
110 | """Activate pylab mode in the user's namespace. | |||
|
111 | ||||
|
112 | Loads and initializes numpy, matplotlib and friends for interactive use. | |||
|
113 | ||||
|
114 | Parameters | |||
|
115 | ---------- | |||
|
116 | user_ns : dict | |||
|
117 | Namespace where the imports will occur. | |||
|
118 | ||||
|
119 | gui : optional, string | |||
|
120 | A valid gui name following the conventions of the %gui magic. | |||
|
121 | ||||
|
122 | import_all : optional, boolean | |||
|
123 | If true, an 'import *' is done from numpy and pylab. | |||
|
124 | ||||
|
125 | Returns | |||
|
126 | ------- | |||
|
127 | The actual gui used (if not given as input, it was obtained from matplotlib | |||
|
128 | itself, and will be needed next to configure IPython's gui integration. | |||
|
129 | """ | |||
|
130 | gui, backend = find_gui_and_backend(gui) | |||
|
131 | activate_matplotlib(backend) | |||
|
132 | import_pylab(user_ns) | |||
101 |
|
133 | |||
102 | print """ |
|
134 | print """ | |
103 | Welcome to pylab, a matplotlib-based Python environment [backend: %s]. |
|
135 | Welcome to pylab, a matplotlib-based Python environment [backend: %s]. |
@@ -3,6 +3,7 b' launchers.' | |||||
3 | """ |
|
3 | """ | |
4 |
|
4 | |||
5 | # Standard library imports. |
|
5 | # Standard library imports. | |
|
6 | import os | |||
6 | import socket |
|
7 | import socket | |
7 | from subprocess import Popen |
|
8 | from subprocess import Popen | |
8 | import sys |
|
9 | import sys | |
@@ -63,7 +64,10 b' def make_kernel(namespace, kernel_factory,' | |||||
63 | """ Creates a kernel. |
|
64 | """ Creates a kernel. | |
64 | """ |
|
65 | """ | |
65 | # Install minimal exception handling |
|
66 | # Install minimal exception handling | |
66 | sys.excepthook = FormattedTB(mode='Verbose', ostream=sys.__stdout__) |
|
67 | color_scheme = 'LightBG' if sys.platform == 'darwin' else 'Linux' | |
|
68 | sys.excepthook = FormattedTB( | |||
|
69 | mode='Verbose', color_scheme=color_scheme, ostream=sys.__stdout__ | |||
|
70 | ) | |||
67 |
|
71 | |||
68 | # Create a context, a session, and the kernel sockets. |
|
72 | # Create a context, a session, and the kernel sockets. | |
69 | io.rprint("Starting the kernel...") |
|
73 | io.rprint("Starting the kernel...") | |
@@ -84,6 +88,7 b' def make_kernel(namespace, kernel_factory,' | |||||
84 |
|
88 | |||
85 | # Redirect input streams and set a display hook. |
|
89 | # Redirect input streams and set a display hook. | |
86 | if out_stream_factory: |
|
90 | if out_stream_factory: | |
|
91 | pass | |||
87 | sys.stdout = out_stream_factory(session, pub_socket, u'stdout') |
|
92 | sys.stdout = out_stream_factory(session, pub_socket, u'stdout') | |
88 | sys.stderr = out_stream_factory(session, pub_socket, u'stderr') |
|
93 | sys.stderr = out_stream_factory(session, pub_socket, u'stderr') | |
89 | if display_hook_factory: |
|
94 | if display_hook_factory: |
@@ -27,8 +27,8 b' import zmq' | |||||
27 | # Local imports. |
|
27 | # Local imports. | |
28 | from IPython.config.configurable import Configurable |
|
28 | from IPython.config.configurable import Configurable | |
29 | from IPython.utils import io |
|
29 | from IPython.utils import io | |
|
30 | from IPython.lib import pylabtools | |||
30 | from IPython.utils.traitlets import Instance |
|
31 | from IPython.utils.traitlets import Instance | |
31 | from completer import KernelCompleter |
|
|||
32 | from entry_point import base_launch_kernel, make_argument_parser, make_kernel, \ |
|
32 | from entry_point import base_launch_kernel, make_argument_parser, make_kernel, \ | |
33 | start_kernel |
|
33 | start_kernel | |
34 | from iostream import OutStream |
|
34 | from iostream import OutStream | |
@@ -51,15 +51,6 b' class Kernel(Configurable):' | |||||
51 | pub_socket = Instance('zmq.Socket') |
|
51 | pub_socket = Instance('zmq.Socket') | |
52 | req_socket = Instance('zmq.Socket') |
|
52 | req_socket = Instance('zmq.Socket') | |
53 |
|
53 | |||
54 | # Maps user-friendly backend names to matplotlib backend identifiers. |
|
|||
55 | _pylab_map = { 'tk': 'TkAgg', |
|
|||
56 | 'gtk': 'GTKAgg', |
|
|||
57 | 'wx': 'WXAgg', |
|
|||
58 | 'qt': 'Qt4Agg', # qt3 not supported |
|
|||
59 | 'qt4': 'Qt4Agg', |
|
|||
60 | 'payload-svg' : \ |
|
|||
61 | 'module://IPython.zmq.pylab.backend_payload_svg' } |
|
|||
62 |
|
||||
63 | def __init__(self, **kwargs): |
|
54 | def __init__(self, **kwargs): | |
64 | super(Kernel, self).__init__(**kwargs) |
|
55 | super(Kernel, self).__init__(**kwargs) | |
65 |
|
56 | |||
@@ -79,61 +70,33 b' class Kernel(Configurable):' | |||||
79 | for msg_type in msg_types: |
|
70 | for msg_type in msg_types: | |
80 | self.handlers[msg_type] = getattr(self, msg_type) |
|
71 | self.handlers[msg_type] = getattr(self, msg_type) | |
81 |
|
72 | |||
82 | def activate_pylab(self, backend=None, import_all=True): |
|
73 | def do_one_iteration(self): | |
83 | """ Activates pylab in this kernel's namespace. |
|
74 | try: | |
84 |
|
75 | ident = self.reply_socket.recv(zmq.NOBLOCK) | ||
85 | Parameters: |
|
76 | except zmq.ZMQError, e: | |
86 | ----------- |
|
77 | if e.errno == zmq.EAGAIN: | |
87 | backend : str, optional |
|
78 | return | |
88 | A valid backend name. |
|
|||
89 |
|
||||
90 | import_all : bool, optional |
|
|||
91 | If true, an 'import *' is done from numpy and pylab. |
|
|||
92 | """ |
|
|||
93 | # FIXME: This is adapted from IPython.lib.pylabtools.pylab_activate. |
|
|||
94 | # Common functionality should be refactored. |
|
|||
95 |
|
||||
96 | # We must set the desired backend before importing pylab. |
|
|||
97 | import matplotlib |
|
|||
98 | if backend: |
|
|||
99 | backend_id = self._pylab_map[backend] |
|
|||
100 | if backend_id.startswith('module://'): |
|
|||
101 | # Work around bug in matplotlib: matplotlib.use converts the |
|
|||
102 | # backend_id to lowercase even if a module name is specified! |
|
|||
103 | matplotlib.rcParams['backend'] = backend_id |
|
|||
104 | else: |
|
79 | else: | |
105 |
|
|
80 | raise | |
106 |
|
81 | # FIXME: Bug in pyzmq/zmq? | ||
107 | # Import numpy as np/pyplot as plt are conventions we're trying to |
|
82 | # assert self.reply_socket.rcvmore(), "Missing message part." | |
108 | # somewhat standardize on. Making them available to users by default |
|
83 | msg = self.reply_socket.recv_json() | |
109 | # will greatly help this. |
|
84 | omsg = Message(msg) | |
110 | exec ("import numpy\n" |
|
85 | io.rprint('\n') | |
111 | "import matplotlib\n" |
|
86 | io.rprint(omsg) | |
112 | "from matplotlib import pylab, mlab, pyplot\n" |
|
87 | handler = self.handlers.get(omsg.msg_type, None) | |
113 | "np = numpy\n" |
|
88 | if handler is None: | |
114 | "plt = pyplot\n" |
|
89 | io.rprinte("UNKNOWN MESSAGE TYPE:", omsg) | |
115 | ) in self.shell.user_ns |
|
90 | else: | |
116 |
|
91 | handler(ident, omsg) | ||
117 | if import_all: |
|
|||
118 | exec("from matplotlib.pylab import *\n" |
|
|||
119 | "from numpy import *\n") in self.shell.user_ns |
|
|||
120 |
|
||||
121 | matplotlib.interactive(True) |
|
|||
122 |
|
92 | |||
123 | def start(self): |
|
93 | def start(self): | |
124 | """ Start the kernel main loop. |
|
94 | """ Start the kernel main loop. | |
125 | """ |
|
95 | """ | |
126 | while True: |
|
96 | while True: | |
127 | ident = self.reply_socket.recv() |
|
97 | time.sleep(0.05) | |
128 | assert self.reply_socket.rcvmore(), "Missing message part." |
|
98 | self.do_one_iteration() | |
129 | msg = self.reply_socket.recv_json() |
|
99 | ||
130 | omsg = Message(msg) |
|
|||
131 | io.rprint('\n', omsg) |
|
|||
132 | handler = self.handlers.get(omsg.msg_type, None) |
|
|||
133 | if handler is None: |
|
|||
134 | io.rprinte("UNKNOWN MESSAGE TYPE:", omsg) |
|
|||
135 | else: |
|
|||
136 | handler(ident, omsg) |
|
|||
137 |
|
100 | |||
138 | #--------------------------------------------------------------------------- |
|
101 | #--------------------------------------------------------------------------- | |
139 | # Kernel request handlers |
|
102 | # Kernel request handlers | |
@@ -331,6 +294,82 b' class Kernel(Configurable):' | |||||
331 |
|
294 | |||
332 | return symbol, [] |
|
295 | return symbol, [] | |
333 |
|
296 | |||
|
297 | ||||
|
298 | class QtKernel(Kernel): | |||
|
299 | """A Kernel subclass with Qt support.""" | |||
|
300 | ||||
|
301 | def start(self): | |||
|
302 | """Start a kernel with QtPy4 event loop integration.""" | |||
|
303 | ||||
|
304 | from PyQt4 import QtGui, QtCore | |||
|
305 | self.app = QtGui.QApplication([]) | |||
|
306 | self.app.setQuitOnLastWindowClosed (False) | |||
|
307 | self.timer = QtCore.QTimer() | |||
|
308 | self.timer.timeout.connect(self.do_one_iteration) | |||
|
309 | self.timer.start(50) | |||
|
310 | self.app.exec_() | |||
|
311 | ||||
|
312 | ||||
|
313 | class WxKernel(Kernel): | |||
|
314 | """A Kernel subclass with Wx support.""" | |||
|
315 | ||||
|
316 | def start(self): | |||
|
317 | """Start a kernel with wx event loop support.""" | |||
|
318 | ||||
|
319 | import wx | |||
|
320 | doi = self.do_one_iteration | |||
|
321 | ||||
|
322 | # We have to put the wx.Timer in a wx.Frame for it to fire properly. | |||
|
323 | # We make the Frame hidden when we create it in the main app below. | |||
|
324 | class TimerFrame(wx.Frame): | |||
|
325 | def __init__(self, func): | |||
|
326 | wx.Frame.__init__(self, None, -1) | |||
|
327 | self.timer = wx.Timer(self) | |||
|
328 | self.timer.Start(50) | |||
|
329 | self.Bind(wx.EVT_TIMER, self.on_timer) | |||
|
330 | self.func = func | |||
|
331 | def on_timer(self, event): | |||
|
332 | self.func() | |||
|
333 | ||||
|
334 | # We need a custom wx.App to create our Frame subclass that has the | |||
|
335 | # wx.Timer to drive the ZMQ event loop. | |||
|
336 | class IPWxApp(wx.App): | |||
|
337 | def OnInit(self): | |||
|
338 | self.frame = TimerFrame(doi) | |||
|
339 | self.frame.Show(False) | |||
|
340 | return True | |||
|
341 | ||||
|
342 | # The redirect=False here makes sure that wx doesn't replace | |||
|
343 | # sys.stdout/stderr with its own classes. | |||
|
344 | self.app = IPWxApp(redirect=False) | |||
|
345 | self.app.MainLoop() | |||
|
346 | ||||
|
347 | ||||
|
348 | class TkKernel(Kernel): | |||
|
349 | """A Kernel subclass with Tk support.""" | |||
|
350 | ||||
|
351 | def start(self): | |||
|
352 | """Start a Tk enabled event loop.""" | |||
|
353 | ||||
|
354 | import Tkinter | |||
|
355 | doi = self.do_one_iteration | |||
|
356 | ||||
|
357 | # For Tkinter, we create a Tk object and call its withdraw method. | |||
|
358 | class Timer(object): | |||
|
359 | def __init__(self, func): | |||
|
360 | self.app = Tkinter.Tk() | |||
|
361 | self.app.withdraw() | |||
|
362 | self.func = func | |||
|
363 | def on_timer(self): | |||
|
364 | self.func() | |||
|
365 | self.app.after(50, self.on_timer) | |||
|
366 | def start(self): | |||
|
367 | self.on_timer() # Call it once to get things going. | |||
|
368 | self.app.mainloop() | |||
|
369 | ||||
|
370 | self.timer = Timer(doi) | |||
|
371 | self.timer.start() | |||
|
372 | ||||
334 | #----------------------------------------------------------------------------- |
|
373 | #----------------------------------------------------------------------------- | |
335 | # Kernel main and launch functions |
|
374 | # Kernel main and launch functions | |
336 | #----------------------------------------------------------------------------- |
|
375 | #----------------------------------------------------------------------------- | |
@@ -387,13 +426,30 b" given, the GUI backend is matplotlib's, otherwise use one of: \\" | |||||
387 | ['tk', 'gtk', 'qt', 'wx', 'payload-svg'].") |
|
426 | ['tk', 'gtk', 'qt', 'wx', 'payload-svg'].") | |
388 | namespace = parser.parse_args() |
|
427 | namespace = parser.parse_args() | |
389 |
|
428 | |||
390 | kernel = make_kernel(namespace, Kernel, OutStream) |
|
429 | kernel_class = Kernel | |
|
430 | ||||
|
431 | _kernel_classes = { | |||
|
432 | 'qt' : QtKernel, | |||
|
433 | 'qt4' : QtKernel, | |||
|
434 | 'payload-svg':Kernel, | |||
|
435 | 'wx' : WxKernel, | |||
|
436 | 'tk' : TkKernel | |||
|
437 | } | |||
391 | if namespace.pylab: |
|
438 | if namespace.pylab: | |
392 | if namespace.pylab == 'auto': |
|
439 | if namespace.pylab == 'auto': | |
393 | kernel.activate_pylab() |
|
440 | gui, backend = pylabtools.find_gui_and_backend() | |
394 | else: |
|
441 | else: | |
395 | kernel.activate_pylab(namespace.pylab) |
|
442 | gui, backend = pylabtools.find_gui_and_backend(namespace.pylab) | |
396 |
|
443 | kernel_class = _kernel_classes.get(gui) | ||
|
444 | if kernel_class is None: | |||
|
445 | raise ValueError('GUI is not supported: %r' % gui) | |||
|
446 | pylabtools.activate_matplotlib(backend) | |||
|
447 | ||||
|
448 | kernel = make_kernel(namespace, kernel_class, OutStream) | |||
|
449 | ||||
|
450 | if namespace.pylab: | |||
|
451 | pylabtools.import_pylab(kernel.shell.user_ns) | |||
|
452 | ||||
397 | start_kernel(namespace, kernel) |
|
453 | start_kernel(namespace, kernel) | |
398 |
|
454 | |||
399 | if __name__ == '__main__': |
|
455 | if __name__ == '__main__': |
@@ -15,7 +15,7 b' from IPython.utils.traitlets import Instance, Type, Dict' | |||||
15 | from IPython.utils.warn import warn |
|
15 | from IPython.utils.warn import warn | |
16 | from IPython.zmq.session import extract_header |
|
16 | from IPython.zmq.session import extract_header | |
17 | from IPython.core.payloadpage import install_payload_page |
|
17 | from IPython.core.payloadpage import install_payload_page | |
18 |
|
18 | from session import Session | ||
19 |
|
19 | |||
20 | # Install the payload version of page. |
|
20 | # Install the payload version of page. | |
21 | install_payload_page() |
|
21 | install_payload_page() | |
@@ -23,7 +23,7 b' install_payload_page()' | |||||
23 |
|
23 | |||
24 | class ZMQDisplayHook(DisplayHook): |
|
24 | class ZMQDisplayHook(DisplayHook): | |
25 |
|
25 | |||
26 |
session = Instance( |
|
26 | session = Instance(Session) | |
27 | pub_socket = Instance('zmq.Socket') |
|
27 | pub_socket = Instance('zmq.Socket') | |
28 | parent_header = Dict({}) |
|
28 | parent_header = Dict({}) | |
29 |
|
29 |
General Comments 0
You need to be logged in to leave comments.
Login now