qtconsole.txt
271 lines
| 10.1 KiB
| text/plain
|
TextLexer
MinRK
|
r3220 | .. _qtconsole: | ||
========================= | ||||
IPython as a QtGUI widget | ||||
========================= | ||||
We now have a version of IPython, using the new two-process :ref:`ZeroMQ Kernel <ipythonzmq>`, | ||||
running in a PyQt_ GUI. | ||||
Overview | ||||
======== | ||||
The Qt frontend has hand-coded emacs-style bindings for text navigation. This is not yet | ||||
configurable. | ||||
.. seealso:: | ||||
Thomas Kluyver
|
r3936 | :ref:`The original IPython-Qt project description. <ipython_qt>` | ||
MinRK
|
r3220 | |||
``%loadpy`` | ||||
=========== | ||||
The ``%loadpy`` magic has been added, just for the GUI frontend. It takes any python | ||||
script (must end in '.py'), and pastes its contents as your next input, so you can edit it | ||||
before executing. The script may be on your machine, but you can also specify a url, and | ||||
it will download the script from the web. This is particularly useful for playing with | ||||
examples from documentation, such as matplotlib. | ||||
.. sourcecode:: ipython | ||||
In [6]: %loadpy | ||||
http://matplotlib.sourceforge.net/plot_directive/mpl_examples/mplot3d/contour3d_demo.py | ||||
In [7]: from mpl_toolkits.mplot3d import axes3d | ||||
...: import matplotlib.pyplot as plt | ||||
...: | ||||
...: fig = plt.figure() | ||||
...: ax = fig.add_subplot(111, projection='3d') | ||||
...: X, Y, Z = axes3d.get_test_data(0.05) | ||||
...: cset = ax.contour(X, Y, Z) | ||||
...: ax.clabel(cset, fontsize=9, inline=1) | ||||
...: | ||||
...: plt.show() | ||||
Pylab | ||||
===== | ||||
One of the most exciting features of the new console is embedded matplotlib figures. You | ||||
can use any standard matplotlib GUI backend (Except native MacOSX) to draw the figures, | ||||
and since there is now a two-process model, there is no longer a conflict between user | ||||
input and the drawing eventloop. | ||||
.. image:: figs/besselj.png | ||||
:width: 519px | ||||
.. pastefig: | ||||
:func:`pastefig` | ||||
**************** | ||||
An additional function, :func:`pastefig`, will be added to the global namespace if you | ||||
MinRK
|
r3976 | specify the ``pylab`` argument. This takes the active figures in matplotlib, and embeds | ||
MinRK
|
r3220 | them in your document. This is especially useful for saving_ your work. | ||
.. _inline: | ||||
MinRK
|
r3976 | ``pylab=inline`` | ||
MinRK
|
r3220 | ****************** | ||
If you want to have all of your figures embedded in your session, instead of calling | ||||
MinRK
|
r3976 | :func:`pastefig`, you can specify ``pylab=inline``, and each time you make a plot, it | ||
MinRK
|
r3220 | will show up in your document, as if you had called :func:`pastefig`. | ||
.. _saving: | ||||
Saving and Printing | ||||
=================== | ||||
IPythonQt has the ability to save your current session, as either HTML or XHTML. If you | ||||
Thomas Kluyver
|
r3936 | have been using :func:`pastefig` or inline_ pylab, your figures will be PNG | ||
MinRK
|
r3220 | in HTML, or inlined as SVG in XHTML. PNG images have the option to be either in an | ||
external folder, as in many browsers' "Webpage, Complete" option, or inlined as well, for | ||||
a larger, but more portable file. | ||||
The widget also exposes the ability to print directly, via the default print shortcut or | ||||
context menu. | ||||
.. Note:: | ||||
MinRK
|
r3976 | Saving is only available to richtext Qt widgets, which are used by default, but | ||
if you pass the ``--plain`` flag, saving will not be available to you. | ||||
MinRK
|
r3220 | |||
See these examples of :download:`png/html<figs/jn.html>` and :download:`svg/xhtml | ||||
<figs/jn.xhtml>` output. Note that syntax highlighting does not survive export. This is a known | ||||
issue, and is being investigated. | ||||
Colors and Highlighting | ||||
======================= | ||||
Terminal IPython has always had some coloring, but never syntax highlighting. There are a | ||||
MinRK
|
r3976 | few simple color choices, specified by the ``colors`` flag or ``%colors`` magic: | ||
MinRK
|
r3220 | |||
* LightBG for light backgrounds | ||||
* Linux for dark backgrounds | ||||
* NoColor for a simple colorless terminal | ||||
MinRK
|
r3976 | The Qt widget has full support for the ``colors`` flag used in the terminal shell. | ||
MinRK
|
r3220 | |||
The Qt widget, however, has full syntax highlighting as you type, handled by the | ||||
MinRK
|
r3976 | `pygments`_ library. The ``style`` argument exposes access to any style by name that can | ||
be found by pygments, and there are several already installed. The ``colors`` argument, | ||||
MinRK
|
r3220 | if unspecified, will be guessed based on the chosen style. Similarly, there are default | ||
MinRK
|
r3976 | styles associated with each ``colors`` option. | ||
MinRK
|
r3220 | |||
MinRK
|
r4127 | Screenshot of ``ipython qtconsole colors=linux``, which uses the 'monokai' theme by | ||
MinRK
|
r3220 | default: | ||
MinRK
|
r3315 | .. image:: figs/colors_dark.png | ||
MinRK
|
r3220 | :width: 627px | ||
.. Note:: | ||||
MinRK
|
r4127 | Calling ``ipython qtconsole -h`` will show all the style names that pygments can find | ||
MinRK
|
r3220 | on your system. | ||
You can also pass the filename of a custom CSS stylesheet, if you want to do your own | ||||
MinRK
|
r3976 | coloring, via the ``stylesheet`` argument. The default LightBG stylesheet: | ||
MinRK
|
r3220 | |||
.. sourcecode:: css | ||||
QPlainTextEdit, QTextEdit { background-color: white; | ||||
color: black ; | ||||
selection-background-color: #ccc} | ||||
.error { color: red; } | ||||
.in-prompt { color: navy; } | ||||
.in-prompt-number { font-weight: bold; } | ||||
.out-prompt { color: darkred; } | ||||
.out-prompt-number { font-weight: bold; } | ||||
MinRK
|
r3976 | Fonts | ||
===== | ||||
The QtConsole has configurable via the ConsoleWidget. To change these, set the ``font_family`` | ||||
or ``font_size`` traits of the ConsoleWidget. For instance, to use 9pt Anonymous Pro:: | ||||
MinRK
|
r4127 | $> ipython qtconsole ConsoleWidget.font_family="Anonymous Pro" ConsoleWidget.font_size=9 | ||
MinRK
|
r3976 | |||
MinRK
|
r3220 | Process Management | ||
================== | ||||
With the two-process ZMQ model, the frontend does not block input during execution. This | ||||
means that actions can be taken by the frontend while the Kernel is executing, or even | ||||
after it crashes. The most basic such command is via 'Ctrl-.', which restarts the kernel. | ||||
This can be done in the middle of a blocking execution. The frontend can also know, via a | ||||
heartbeat mechanism, that the kernel has died. This means that the frontend can safely | ||||
restart the kernel. | ||||
Multiple Consoles | ||||
***************** | ||||
Since the Kernel listens on the network, multiple frontends can connect to it. These | ||||
do not have to all be qt frontends - any IPython frontend can connect and run code. | ||||
MinRK
|
r4127 | When you start ipython qtconsole, there will be an output line, like:: | ||
MinRK
|
r3220 | |||
To connect another client to this kernel, use: | ||||
MinRK
|
r3976 | --external shell=62109 iopub=62110 stdin=62111 hb=62112 | ||
MinRK
|
r3220 | |||
Other frontends can connect to your kernel, and share in the execution. This is great for | ||||
collaboration. The `-e` flag is for 'external'. Starting other consoles with that flag | ||||
will not try to start their own, but rather connect to yours. Ultimately, you will not | ||||
have to specify each port individually, but for now this copy-paste method is best. | ||||
By default (for security reasons), the kernel only listens on localhost, so you can only | ||||
connect multiple frontends to the kernel from your local machine. You can specify to | ||||
MinRK
|
r3976 | listen on an external interface by specifying the ``ip`` argument:: | ||
MinRK
|
r3220 | |||
MinRK
|
r4127 | $> ipython qtconsole ip=192.168.1.123 | ||
MinRK
|
r3220 | |||
If you specify the ip as 0.0.0.0, that refers to all interfaces, so any computer that can | ||||
see yours can connect to the kernel. | ||||
.. warning:: | ||||
Since the ZMQ code currently has no security, listening on an external-facing IP | ||||
is dangerous. You are giving any computer that can see you on the network the ability | ||||
to issue arbitrary shell commands as you on your machine. Be very careful with this. | ||||
Stopping Kernels and Consoles | ||||
***************************** | ||||
Since there can be many consoles per kernel, the shutdown mechanism and dialog are | ||||
probably more complicated than you are used to. Since you don't always want to shutdown a | ||||
kernel when you close a window, you are given the option to just close the console window | ||||
or also close the Kernel and *all other windows*. Note that this only refers to all other | ||||
*local* windows, as remote Consoles are not allowed to shutdown the kernel, and shutdowns | ||||
do not close Remote consoles (to allow for saving, etc.). | ||||
Rules: | ||||
* Restarting the kernel automatically clears all *local* Consoles, and prompts remote | ||||
Consoles about the reset. | ||||
* Shutdown closes all *local* Consoles, and notifies remotes that | ||||
the Kernel has been shutdown. | ||||
* Remote Consoles may not restart or shutdown the kernel. | ||||
MinRK
|
r4132 | Qt and the QtConsole | ||
==================== | ||||
An important part of working with the QtConsole when you are writing your own Qt code is | ||||
to remember that user code (in the kernel) is *not* in the same process as the frontend. | ||||
This means that there is not necessarily any Qt code running in the kernel, and under most | ||||
normal circumstances there isn't. If, however, you specify ``pylab=qt`` at the | ||||
command-line, then there *will* be a :class:`QCoreApplication` instance running in the | ||||
kernel process along with user-code. To get a reference to this application, do: | ||||
.. sourcecode:: python | ||||
from PyQt4 import QtCore | ||||
app = QtCore.QCoreApplication.instance() | ||||
# app will be None if there is no such instance | ||||
A common problem listed in the PyQt4 Gotchas_ is the fact that Python's garbage collection | ||||
will destroy Qt objects (Windows, etc.) once there is no longer a Python reference to | ||||
them, so you have to hold on to them. For instance, in: | ||||
.. sourcecode:: python | ||||
def make_window(): | ||||
win = QtGui.QMainWindow() | ||||
def make_and_return_window(): | ||||
win = QtGui.QMainWindow() | ||||
return win | ||||
:func:`make_window` will never draw a window, because garbage collection will destroy it | ||||
before it is drawn, whereas :func:`make_and_return_window` lets the caller decide when the | ||||
window object should be destroyed. If, as a developer, you know that you always want your | ||||
objects to last as long as the process, you can attach them to the QApplication instance | ||||
itself: | ||||
.. sourcecode:: python | ||||
# do this just once: | ||||
app = QtCore.QCoreApplication.instance() | ||||
app.references = set() | ||||
# then when you create Windows, add them to the set | ||||
def make_window(): | ||||
win = QtGui.QMainWindow() | ||||
app.references.add(win) | ||||
Now the QApplication itself holds a reference to ``win``, so it will never be | ||||
garbage collected until the application itself is destroyed. | ||||
.. _Gotchas: http://www.riverbankcomputing.co.uk/static/Docs/PyQt4/html/gotchas.html#garbage-collection | ||||
MinRK
|
r3220 | |||
Regressions | ||||
=========== | ||||
There are some features, where the qt console lags behind the Terminal frontend. We hope | ||||
to have these fixed by 0.11 release. | ||||
* !cmd input: Due to our use of pexpect, we cannot pass input to subprocesses launched | ||||
using the '!' escape. (this will not be fixed). | ||||
.. [PyQt] PyQt4 http://www.riverbankcomputing.co.uk/software/pyqt/download | ||||
.. [pygments] Pygments http://pygments.org/ | ||||