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,9 +111,7 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 | 114 |
|
|
116 | else: | |
|
117 | 115 |
|
|
118 | 116 | return True |
|
119 | 117 |
@@ -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 |
|
|
|
341 |
|
|
|
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 |
|
|
|
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, |
|
|
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 |
@@ -558,10 +565,16 b' def launch_kernel(xrep_port=0, pub_port=0, req_port=0, independent=False):' | |||
|
558 | 565 | if req_port <= 0: |
|
559 | 566 | req_port = ports.pop(0) |
|
560 | 567 | |
|
561 | # Spawn a kernel. | |
|
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,22 +433,21 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 | #-------------------------------------------------------------------------- |
@@ -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