##// END OF EJS Templates
* The SVG payload matplotlib backend now works....
epatters -
Show More
@@ -0,0 +1,54 b''
1 """ A demo of Qt console-style IPython frontend.
2 """
3
4 # Systemm library imports
5 from PyQt4 import QtCore, QtGui
6
7 # Local imports
8 from IPython.external.argparse import ArgumentParser
9 from IPython.frontend.qt.kernelmanager import QtKernelManager
10 from ipython_widget import IPythonWidget
11 from rich_ipython_widget import RichIPythonWidget
12
13
14 def main():
15 """ Entry point for demo.
16 """
17 # Parse command line arguments.
18 parser = ArgumentParser()
19 parser.add_argument('--pylab', action='store_true',
20 help='start kernel with pylab enabled')
21 parser.add_argument('--rich', action='store_true',
22 help='use rich text frontend')
23 namespace = parser.parse_args()
24
25 # Don't let Qt or ZMQ swallow KeyboardInterupts.
26 import signal
27 signal.signal(signal.SIGINT, signal.SIG_DFL)
28
29 # Create a KernelManager and start a kernel.
30 kernel_manager = QtKernelManager()
31 if namespace.pylab:
32 if namespace.rich:
33 kernel_manager.start_kernel(pylab='payload-svg')
34 else:
35 kernel_manager.start_kernel(pylab='qt4')
36 else:
37 kernel_manager.start_kernel()
38 kernel_manager.start_channels()
39
40 # Launch the application.
41 app = QtGui.QApplication([])
42 if namespace.rich:
43 widget = RichIPythonWidget()
44 else:
45 widget = IPythonWidget()
46 widget.kernel_manager = kernel_manager
47 widget.setWindowTitle('Python')
48 widget.resize(640, 480)
49 widget.show()
50 app.exec_()
51
52
53 if __name__ == '__main__':
54 main()
@@ -0,0 +1,43 b''
1 # System library imports
2 from PyQt4 import QtCore, QtGui
3
4 # Local imports
5 from IPython.frontend.qt.util import image_from_svg
6 from ipython_widget import IPythonWidget
7
8
9 class RichIPythonWidget(IPythonWidget):
10 """ An IPythonWidget that supports rich text, including lists, images, and
11 tables. Note that raw performance will be reduced compared to the plain
12 text version.
13 """
14
15 #---------------------------------------------------------------------------
16 # 'QObject' interface
17 #---------------------------------------------------------------------------
18
19 def __init__(self, parent=None):
20 """ Create a RichIPythonWidget.
21 """
22 super(RichIPythonWidget, self).__init__(kind='rich', parent=parent)
23
24 #---------------------------------------------------------------------------
25 # 'FrontendWidget' interface
26 #---------------------------------------------------------------------------
27
28 def _handle_execute_payload(self, payload):
29 """ Reimplemented to handle pylab plot payloads.
30 """
31 super(RichIPythonWidget, self)._handle_execute_payload(payload)
32
33 plot_payload = payload.get('plot', None)
34 if plot_payload and plot_payload['format'] == 'svg':
35 try:
36 image = image_from_svg(plot_payload['data'])
37 except ValueError:
38 self._append_plain_text('Received invalid plot data.')
39 else:
40 cursor = self._get_end_cursor()
41 cursor.insertBlock()
42 cursor.insertImage(image)
43 cursor.insertBlock()
@@ -111,10 +111,8 b' class CallTipWidget(QtGui.QLabel):'
111 111 point = text_edit.mapToGlobal(point)
112 112 self.move(point)
113 113 self.setText(tip)
114 if self.isVisible():
115 self.resize(self.sizeHint())
116 else:
117 self.show()
114 self.resize(self.sizeHint())
115 self.show()
118 116 return True
119 117
120 118 #--------------------------------------------------------------------------
@@ -337,12 +337,16 b' class FrontendWidget(HistoryConsoleWidget):'
337 337 # before writing a new prompt.
338 338 self.kernel_manager.sub_channel.flush()
339 339
340 status = reply['content']['status']
341 if status == 'error':
340 content = reply['content']
341 status = content['status']
342 if status == 'ok':
343 self._handle_execute_payload(content['payload'])
344 elif status == 'error':
342 345 self._handle_execute_error(reply)
343 346 elif status == 'aborted':
344 347 text = "ERROR: ABORTED\n"
345 348 self._append_plain_text(text)
349
346 350 self._hidden = True
347 351 self._show_interpreter_prompt()
348 352 self.executed.emit(reply)
@@ -352,6 +356,9 b' class FrontendWidget(HistoryConsoleWidget):'
352 356 traceback = ''.join(content['traceback'])
353 357 self._append_plain_text(traceback)
354 358
359 def _handle_execute_payload(self, payload):
360 pass
361
355 362 def _handle_complete_reply(self, rep):
356 363 cursor = self._get_cursor()
357 364 if rep['parent_header']['msg_id'] == self._complete_id and \
@@ -182,25 +182,3 b' class IPythonWidget(FrontendWidget):'
182 182 """
183 183 block = self._control.document().lastBlock()
184 184 self._previous_prompt_blocks.append((block, block.length()))
185
186
187 if __name__ == '__main__':
188 from IPython.frontend.qt.kernelmanager import QtKernelManager
189
190 # Don't let Qt or ZMQ swallow KeyboardInterupts.
191 import signal
192 signal.signal(signal.SIGINT, signal.SIG_DFL)
193
194 # Create a KernelManager.
195 kernel_manager = QtKernelManager()
196 kernel_manager.start_kernel()
197 kernel_manager.start_channels()
198
199 # Launch the application.
200 app = QtGui.QApplication([])
201 widget = IPythonWidget()
202 widget.kernel_manager = kernel_manager
203 widget.setWindowTitle('Python')
204 widget.resize(640, 480)
205 widget.show()
206 app.exec_()
@@ -153,10 +153,6 b' class QtKernelManager(KernelManager, QtCore.QObject):'
153 153 xreq_channel_class = QtXReqSocketChannel
154 154 rep_channel_class = QtRepSocketChannel
155 155
156 def __init__(self, *args, **kw):
157 QtCore.QObject.__init__(self)
158 KernelManager.__init__(self, *args, **kw)
159
160 156 #---------------------------------------------------------------------------
161 157 # 'object' interface
162 158 #---------------------------------------------------------------------------
@@ -181,15 +181,16 b' class Kernel(object):'
181 181 # FIXME: This is adapted from IPython.lib.pylabtools.pylab_activate.
182 182 # Common funtionality should be refactored.
183 183
184 import matplotlib
185
186 184 # We must set the desired backend before importing pylab.
185 import matplotlib
187 186 if backend:
188 matplotlib.use(self._pylab_map[backend])
189
190 # This must be imported last in the matplotlib series, after
191 # backend/interactivity choices have been made.
192 import matplotlib.pylab as pylab
187 backend_id = self._pylab_map[backend]
188 if backend_id.startswith('module://'):
189 # Work around bug in matplotlib: matplotlib.use converts the
190 # backend_id to lowercase even if a module name is specified!
191 matplotlib.rcParams['backend'] = backend_id
192 else:
193 matplotlib.use(backend_id)
193 194
194 195 # Import numpy as np/pyplot as plt are conventions we're trying to
195 196 # somewhat standardize on. Making them available to users by default
@@ -511,7 +512,8 b" given, the GUI backend is matplotlib's, otherwise use one of: \\"
511 512 kernel.start()
512 513
513 514
514 def launch_kernel(xrep_port=0, pub_port=0, req_port=0, independent=False):
515 def launch_kernel(xrep_port=0, pub_port=0, req_port=0,
516 pylab=False, independent=False):
515 517 """ Launches a localhost kernel, binding to the specified ports.
516 518
517 519 Parameters
@@ -525,6 +527,11 b' def launch_kernel(xrep_port=0, pub_port=0, req_port=0, independent=False):'
525 527 req_port : int, optional
526 528 The port to use for the REQ (raw input) channel.
527 529
530 pylab : bool or string, optional (default False)
531 If not False, the kernel will be launched with pylab enabled. If a
532 string is passed, matplotlib will use the specified backend. Otherwise,
533 matplotlib's default backend will be used.
534
528 535 independent : bool, optional (default False)
529 536 If set, the kernel process is guaranteed to survive if this process
530 537 dies. If not set, an effort is made to ensure that the kernel is killed
@@ -557,11 +564,17 b' def launch_kernel(xrep_port=0, pub_port=0, req_port=0, independent=False):'
557 564 pub_port = ports.pop(0)
558 565 if req_port <= 0:
559 566 req_port = ports.pop(0)
560
561 # Spawn a kernel.
567
568 # Build the kernel launch command.
562 569 command = 'from IPython.zmq.kernel import main; main()'
563 570 arguments = [ sys.executable, '-c', command, '--xrep', str(xrep_port),
564 571 '--pub', str(pub_port), '--req', str(req_port) ]
572 if pylab:
573 arguments.append('--pylab')
574 if isinstance(pylab, basestring):
575 arguments.append(pylab)
576
577 # Spawn a kernel.
565 578 if independent:
566 579 if sys.platform == 'win32':
567 580 proc = Popen(['start', '/b'] + arguments, shell=True)
@@ -433,23 +433,22 b' class KernelManager(HasTraits):'
433 433 # The kernel process with which the KernelManager is communicating.
434 434 kernel = Instance(Popen)
435 435
436 # The addresses for the communication channels.
437 xreq_address = TCPAddress((LOCALHOST, 0))
438 sub_address = TCPAddress((LOCALHOST, 0))
439 rep_address = TCPAddress((LOCALHOST, 0))
440
436 441 # The classes to use for the various channels.
437 442 xreq_channel_class = Type(XReqSocketChannel)
438 443 sub_channel_class = Type(SubSocketChannel)
439 444 rep_channel_class = Type(RepSocketChannel)
440 445
441 446 # Protected traits.
442 xreq_address = TCPAddress((LOCALHOST, 0))
443 sub_address = TCPAddress((LOCALHOST, 0))
444 rep_address = TCPAddress((LOCALHOST, 0))
445 447 _xreq_channel = Any
446 448 _sub_channel = Any
447 449 _rep_channel = Any
448 450
449 def __init__(self, **kwargs):
450 super(KernelManager, self).__init__(**kwargs)
451
452 #--------------------------------- -----------------------------------------
451 #--------------------------------------------------------------------------
453 452 # Channel management methods:
454 453 #--------------------------------------------------------------------------
455 454
@@ -486,11 +485,16 b' class KernelManager(HasTraits):'
486 485 # Kernel process management methods:
487 486 #--------------------------------------------------------------------------
488 487
489 def start_kernel(self):
488 def start_kernel(self, pylab=False):
490 489 """Starts a kernel process and configures the manager to use it.
491 490
492 491 If random ports (port=0) are being used, this method must be called
493 492 before the channels are created.
493
494 Parameters:
495 -----------
496 pylab : bool or string, optional (default False)
497 See IPython.zmq.kernel.launch_kernel for documentation.
494 498 """
495 499 xreq, sub, rep = self.xreq_address, self.sub_address, self.rep_address
496 500 if xreq[0] != LOCALHOST or sub[0] != LOCALHOST or rep[0] != LOCALHOST:
@@ -499,7 +503,7 b' class KernelManager(HasTraits):'
499 503 "configured properly.")
500 504
501 505 self.kernel, xrep, pub, req = launch_kernel(
502 xrep_port=xreq[1], pub_port=sub[1], req_port=rep[1])
506 xrep_port=xreq[1], pub_port=sub[1], req_port=rep[1], pylab=pylab)
503 507 self.xreq_address = (LOCALHOST, xrep)
504 508 self.sub_address = (LOCALHOST, pub)
505 509 self.rep_address = (LOCALHOST, req)
@@ -12,7 +12,7 b' from backend_payload import add_plot_payload'
12 12 def show():
13 13 """ Deliver a SVG payload.
14 14 """
15 figure_manager = Gcf.get_actve()
15 figure_manager = Gcf.get_active()
16 16 if figure_manager is not None:
17 17 data = svg_from_canvas(figure_manager.canvas)
18 18 add_plot_payload('svg', data)
General Comments 0
You need to be logged in to leave comments. Login now