##// END OF EJS Templates
Backport PR #6593: note how to start the qtconsole...
Min RK -
Show More
@@ -1,639 +1,643 b''
1 1 .. _qtconsole:
2 2
3 3 =========================
4 4 A Qt Console for IPython
5 5 =========================
6 6
7 To start the Qt Console::
8
9 ipython qtconsole
10
7 11 We now have a version of IPython, using the new two-process :ref:`ZeroMQ Kernel
8 12 <ipythonzmq>`, running in a PyQt_ GUI. This is a very lightweight widget that
9 13 largely feels like a terminal, but provides a number of enhancements only
10 14 possible in a GUI, such as inline figures, proper multiline editing with syntax
11 15 highlighting, graphical calltips, and much more.
12 16
13 17 .. figure:: ../_images/qtconsole.png
14 18 :width: 400px
15 19 :alt: IPython Qt console with embedded plots
16 20 :align: center
17 21 :target: ../_images/qtconsole.png
18 22
19 23 The Qt console for IPython, using inline matplotlib plots.
20 24
21 25 To get acquainted with the Qt console, type `%guiref` to see a quick
22 26 introduction of its main features.
23 27
24 28 The Qt frontend has hand-coded emacs-style bindings for text navigation. This
25 29 is not yet configurable.
26 30
27 31 .. tip::
28 32
29 33 Since the Qt console tries hard to behave like a terminal, by default it
30 34 immediately executes single lines of input that are complete. If you want
31 35 to force multiline input, hit :kbd:`Ctrl-Enter` at the end of the first line
32 36 instead of :kbd:`Enter`, and it will open a new line for input. At any
33 37 point in a multiline block, you can force its execution (without having to
34 38 go to the bottom) with :kbd:`Shift-Enter`.
35 39
36 40 ``%load``
37 41 =========
38 42
39 43 The new ``%load`` magic (previously ``%loadpy``) takes any script, and pastes
40 44 its contents as your next input, so you can edit it before executing. The
41 45 script may be on your machine, but you can also specify an history range, or a
42 46 url, and it will download the script from the web. This is particularly useful
43 47 for playing with examples from documentation, such as matplotlib.
44 48
45 49 .. sourcecode:: ipython
46 50
47 51 In [6]: %load http://matplotlib.org/plot_directive/mpl_examples/mplot3d/contour3d_demo.py
48 52
49 53 In [7]: from mpl_toolkits.mplot3d import axes3d
50 54 ...: import matplotlib.pyplot as plt
51 55 ...:
52 56 ...: fig = plt.figure()
53 57 ...: ax = fig.add_subplot(111, projection='3d')
54 58 ...: X, Y, Z = axes3d.get_test_data(0.05)
55 59 ...: cset = ax.contour(X, Y, Z)
56 60 ...: ax.clabel(cset, fontsize=9, inline=1)
57 61 ...:
58 62 ...: plt.show()
59 63
60 64 Inline Matplotlib
61 65 =================
62 66
63 67 One of the most exciting features of the QtConsole is embedded matplotlib
64 68 figures. You can use any standard matplotlib GUI backend
65 69 to draw the figures, and since there is now a two-process model, there is no
66 70 longer a conflict between user input and the drawing eventloop.
67 71
68 72 .. image:: figs/besselj.png
69 73 :width: 519px
70 74
71 75 .. _display:
72 76
73 77 :func:`display`
74 78 ***************
75 79
76 80 IPython provides a function :func:`display` for displaying rich representations
77 81 of objects if they are available. The IPython display
78 82 system provides a mechanism for specifying PNG or SVG (and more)
79 83 representations of objects for GUI frontends.
80 84 When you enable matplotlib integration via the ``%matplotlib`` magic, IPython registers
81 85 convenient PNG and SVG renderers for matplotlib figures, so you can embed them
82 86 in your document by calling :func:`display` on one or more of them. This is
83 87 especially useful for saving_ your work.
84 88
85 89 .. sourcecode:: ipython
86 90
87 91 In [4]: from IPython.display import display
88 92
89 93 In [5]: plt.plot(range(5)) # plots in the matplotlib window
90 94
91 95 In [6]: display(plt.gcf()) # embeds the current figure in the qtconsole
92 96
93 97 In [7]: display(*getfigs()) # embeds all active figures in the qtconsole
94 98
95 99 If you have a reference to a matplotlib figure object, you can always display
96 100 that specific figure:
97 101
98 102 .. sourcecode:: ipython
99 103
100 104 In [1]: f = plt.figure()
101 105
102 106 In [2]: plt.plot(np.rand(100))
103 107 Out[2]: [<matplotlib.lines.Line2D at 0x7fc6ac03dd90>]
104 108
105 109 In [3]: display(f)
106 110
107 111 # Plot is shown here
108 112
109 113 In [4]: plt.title('A title')
110 114 Out[4]: <matplotlib.text.Text at 0x7fc6ac023450>
111 115
112 116 In [5]: display(f)
113 117
114 118 # Updated plot with title is shown here.
115 119
116 120 .. _inline:
117 121
118 122 ``--matplotlib inline``
119 123 ***********************
120 124
121 125 If you want to have all of your figures embedded in your session, instead of
122 126 calling :func:`display`, you can specify ``--matplotlib inline`` when you start the
123 127 console, and each time you make a plot, it will show up in your document, as if
124 128 you had called :func:`display(fig)`.
125 129
126 130 The inline backend can use either SVG or PNG figures (PNG being the default).
127 131 It also supports the special key ``'retina'``, which is 2x PNG for high-DPI displays.
128 132 To switch between them, set the ``InlineBackend.figure_format`` configurable
129 133 in a config file, or via the ``%config`` magic:
130 134
131 135 .. sourcecode:: ipython
132 136
133 137 In [10]: %config InlineBackend.figure_format = 'svg'
134 138
135 139 .. note::
136 140
137 141 Changing the inline figure format also affects calls to :func:`display` above,
138 142 even if you are not using the inline backend for all figures.
139 143
140 144 By default, IPython closes all figures at the completion of each execution. This means you
141 145 don't have to manually close figures, which is less convenient when figures aren't attached
142 146 to windows with an obvious close button. It also means that the first matplotlib call in
143 147 each cell will always create a new figure:
144 148
145 149 .. sourcecode:: ipython
146 150
147 151 In [11]: plt.plot(range(100))
148 152 <single-line plot>
149 153
150 154 In [12]: plt.plot([1,3,2])
151 155 <another single-line plot>
152 156
153 157
154 158 However, it does prevent the list of active figures surviving from one input cell to the
155 159 next, so if you want to continue working with a figure, you must hold on to a reference to
156 160 it:
157 161
158 162 .. sourcecode:: ipython
159 163
160 164 In [11]: fig = gcf()
161 165 ....: fig.plot(rand(100))
162 166 <plot>
163 167 In [12]: fig.title('Random Title')
164 168 <redraw plot with title>
165 169
166 170 This behavior is controlled by the :attr:`InlineBackend.close_figures` configurable, and
167 171 if you set it to False, via %config or config file, then IPython will *not* close figures,
168 172 and tools like :func:`gcf`, :func:`gca`, :func:`getfigs` will behave the same as they
169 173 do with other backends. You will, however, have to manually close figures:
170 174
171 175 .. sourcecode:: ipython
172 176
173 177 # close all active figures:
174 178 In [13]: [ fig.close() for fig in getfigs() ]
175 179
176 180
177 181
178 182 .. _saving:
179 183
180 184 Saving and Printing
181 185 ===================
182 186
183 187 IPythonQt has the ability to save your current session, as either HTML or
184 188 XHTML. If you have been using :func:`display` or inline_ matplotlib, your figures
185 189 will be PNG in HTML, or inlined as SVG in XHTML. PNG images have the option to
186 190 be either in an external folder, as in many browsers' "Webpage, Complete"
187 191 option, or inlined as well, for a larger, but more portable file.
188 192
189 193 .. note::
190 194
191 195 Export to SVG+XHTML requires that you are using SVG figures, which is *not*
192 196 the default. To switch the inline figure format to use SVG during an active
193 197 session, do:
194 198
195 199 .. sourcecode:: ipython
196 200
197 201 In [10]: %config InlineBackend.figure_format = 'svg'
198 202
199 203 Or, you can add the same line (c.Inline... instead of %config Inline...) to
200 204 your config files.
201 205
202 206 This will only affect figures plotted after making this call
203 207
204 208
205 209 The widget also exposes the ability to print directly, via the default print
206 210 shortcut or context menu.
207 211
208 212
209 213 .. Note::
210 214
211 215 Saving is only available to richtext Qt widgets, which are used by default,
212 216 but if you pass the ``--plain`` flag, saving will not be available to you.
213 217
214 218
215 219 See these examples of :download:`png/html<figs/jn.html>` and
216 220 :download:`svg/xhtml <figs/jn.xhtml>` output. Note that syntax highlighting
217 221 does not survive export. This is a known issue, and is being investigated.
218 222
219 223
220 224 Colors and Highlighting
221 225 =======================
222 226
223 227 Terminal IPython has always had some coloring, but never syntax
224 228 highlighting. There are a few simple color choices, specified by the ``colors``
225 229 flag or ``%colors`` magic:
226 230
227 231 * LightBG for light backgrounds
228 232 * Linux for dark backgrounds
229 233 * NoColor for a simple colorless terminal
230 234
231 235 The Qt widget has full support for the ``colors`` flag used in the terminal shell.
232 236
233 237 The Qt widget, however, has full syntax highlighting as you type, handled by
234 238 the `pygments`_ library. The ``style`` argument exposes access to any style by
235 239 name that can be found by pygments, and there are several already
236 240 installed. The ``colors`` argument, if unspecified, will be guessed based on
237 241 the chosen style. Similarly, there are default styles associated with each
238 242 ``colors`` option.
239 243
240 244
241 245 Screenshot of ``ipython qtconsole --colors=linux``, which uses the 'monokai'
242 246 theme by default:
243 247
244 248 .. image:: figs/colors_dark.png
245 249 :width: 627px
246 250
247 251 .. Note::
248 252
249 253 Calling ``ipython qtconsole -h`` will show all the style names that
250 254 pygments can find on your system.
251 255
252 256 You can also pass the filename of a custom CSS stylesheet, if you want to do
253 257 your own coloring, via the ``stylesheet`` argument. The default LightBG
254 258 stylesheet:
255 259
256 260 .. sourcecode:: css
257 261
258 262 QPlainTextEdit, QTextEdit { background-color: white;
259 263 color: black ;
260 264 selection-background-color: #ccc}
261 265 .error { color: red; }
262 266 .in-prompt { color: navy; }
263 267 .in-prompt-number { font-weight: bold; }
264 268 .out-prompt { color: darkred; }
265 269 .out-prompt-number { font-weight: bold; }
266 270 /* .inverted is used to highlight selected completion */
267 271 .inverted { background-color: black ; color: white; }
268 272
269 273 Fonts
270 274 =====
271 275
272 276 The QtConsole has configurable via the ConsoleWidget. To change these, set the
273 277 ``font_family`` or ``font_size`` traits of the ConsoleWidget. For instance, to
274 278 use 9pt Anonymous Pro::
275 279
276 280 $> ipython qtconsole --ConsoleWidget.font_family="Anonymous Pro" --ConsoleWidget.font_size=9
277 281
278 282 Process Management
279 283 ==================
280 284
281 285 With the two-process ZMQ model, the frontend does not block input during
282 286 execution. This means that actions can be taken by the frontend while the
283 287 Kernel is executing, or even after it crashes. The most basic such command is
284 288 via 'Ctrl-.', which restarts the kernel. This can be done in the middle of a
285 289 blocking execution. The frontend can also know, via a heartbeat mechanism, that
286 290 the kernel has died. This means that the frontend can safely restart the
287 291 kernel.
288 292
289 293 .. _multiple_consoles:
290 294
291 295 Multiple Consoles
292 296 *****************
293 297
294 298 Since the Kernel listens on the network, multiple frontends can connect to it.
295 299 These do not have to all be qt frontends - any IPython frontend can connect and
296 300 run code. When you start ipython qtconsole, there will be an output line,
297 301 like::
298 302
299 303 [IPKernelApp] To connect another client to this kernel, use:
300 304 [IPKernelApp] --existing kernel-12345.json
301 305
302 306 Other frontends can connect to your kernel, and share in the execution. This is
303 307 great for collaboration. The ``--existing`` flag means connect to a kernel
304 308 that already exists. Starting other consoles
305 309 with that flag will not try to start their own kernel, but rather connect to
306 310 yours. :file:`kernel-12345.json` is a small JSON file with the ip, port, and
307 311 authentication information necessary to connect to your kernel. By default, this file
308 312 will be in your default profile's security directory. If it is somewhere else,
309 313 the output line will print the full path of the connection file, rather than
310 314 just its filename.
311 315
312 316 If you need to find the connection info to send, and don't know where your connection file
313 317 lives, there are a couple of ways to get it. If you are already running an IPython console
314 318 connected to the kernel, you can use the ``%connect_info`` magic to display the information
315 319 necessary to connect another frontend to the kernel.
316 320
317 321 .. sourcecode:: ipython
318 322
319 323 In [2]: %connect_info
320 324 {
321 325 "stdin_port":50255,
322 326 "ip":"127.0.0.1",
323 327 "hb_port":50256,
324 328 "key":"70be6f0f-1564-4218-8cda-31be40a4d6aa",
325 329 "shell_port":50253,
326 330 "iopub_port":50254
327 331 }
328 332
329 333 Paste the above JSON into a file, and connect with:
330 334 $> ipython <app> --existing <file>
331 335 or, if you are local, you can connect with just:
332 336 $> ipython <app> --existing kernel-12345.json
333 337 or even just:
334 338 $> ipython <app> --existing
335 339 if this is the most recent IPython session you have started.
336 340
337 341 Otherwise, you can find a connection file by name (and optionally profile) with
338 342 :func:`IPython.lib.kernel.find_connection_file`:
339 343
340 344 .. sourcecode:: bash
341 345
342 346 $> python -c "from IPython.lib.kernel import find_connection_file;\
343 347 print find_connection_file('kernel-12345.json')"
344 348 /home/you/.ipython/profile_default/security/kernel-12345.json
345 349
346 350 And if you are using a particular IPython profile:
347 351
348 352 .. sourcecode:: bash
349 353
350 354 $> python -c "from IPython.lib.kernel import find_connection_file;\
351 355 print find_connection_file('kernel-12345.json', profile='foo')"
352 356 /home/you/.ipython/profile_foo/security/kernel-12345.json
353 357
354 358 You can even launch a standalone kernel, and connect and disconnect Qt Consoles
355 359 from various machines. This lets you keep the same running IPython session
356 360 on your work machine (with matplotlib plots and everything), logging in from home,
357 361 cafΓ©s, etc.::
358 362
359 363 $> ipython kernel
360 364 [IPKernelApp] To connect another client to this kernel, use:
361 365 [IPKernelApp] --existing kernel-12345.json
362 366
363 367 This is actually exactly the same as the subprocess launched by the qtconsole, so
364 368 all the information about connecting to a standalone kernel is identical to that
365 369 of connecting to the kernel attached to a running console.
366 370
367 371 .. _kernel_security:
368 372
369 373 Security
370 374 --------
371 375
372 376 .. warning::
373 377
374 378 Since the ZMQ code currently has no encryption, listening on an
375 379 external-facing IP is dangerous. You are giving any computer that can see
376 380 you on the network the ability to connect to your kernel, and view your traffic.
377 381 Read the rest of this section before listening on external ports
378 382 or running an IPython kernel on a shared machine.
379 383
380 384 By default (for security reasons), the kernel only listens on localhost, so you
381 385 can only connect multiple frontends to the kernel from your local machine. You
382 386 can specify to listen on an external interface by specifying the ``ip``
383 387 argument::
384 388
385 389 $> ipython qtconsole --ip=192.168.1.123
386 390
387 391 If you specify the ip as 0.0.0.0 or '*', that means all interfaces, so any
388 392 computer that can see yours on the network can connect to the kernel.
389 393
390 394 Messages are not encrypted, so users with access to the ports your kernel is using will be
391 395 able to see any output of the kernel. They will **NOT** be able to issue shell commands as
392 396 you due to message signatures, which are enabled by default as of IPython 0.12.
393 397
394 398 .. warning::
395 399
396 400 If you disable message signatures, then any user with access to the ports your
397 401 kernel is listening on can issue arbitrary code as you. **DO NOT** disable message
398 402 signatures unless you have a lot of trust in your environment.
399 403
400 404 The one security feature IPython does provide is protection from unauthorized execution.
401 405 IPython's messaging system will sign messages with HMAC digests using a shared-key. The key
402 406 is never sent over the network, it is only used to generate a unique hash for each message,
403 407 based on its content. When IPython receives a message, it will check that the digest
404 408 matches, and discard the message. You can use any file that only you have access to to
405 409 generate this key, but the default is just to generate a new UUID. You can generate a random
406 410 private key with::
407 411
408 412 # generate 1024b of random data, and store in a file only you can read:
409 413 # (assumes IPYTHONDIR is defined, otherwise use your IPython directory)
410 414 $> python -c "import os; print os.urandom(128).encode('base64')" > $IPYTHONDIR/sessionkey
411 415 $> chmod 600 $IPYTHONDIR/sessionkey
412 416
413 417 The *contents* of this file will be stored in the JSON connection file, so that file
414 418 contains everything you need to connect to and use a kernel.
415 419
416 420 To use this generated key, simply specify the ``Session.keyfile`` configurable
417 421 in :file:`ipython_config.py` or at the command-line, as in::
418 422
419 423 # instruct IPython to sign messages with that key, instead of a new UUID
420 424 $> ipython qtconsole --Session.keyfile=$IPYTHONDIR/sessionkey
421 425
422 426 .. _ssh_tunnels:
423 427
424 428 SSH Tunnels
425 429 -----------
426 430
427 431 Sometimes you want to connect to machines across the internet, or just across
428 432 a LAN that either doesn't permit open ports or you don't trust the other
429 433 machines on the network. To do this, you can use SSH tunnels. SSH tunnels
430 434 are a way to securely forward ports on your local machine to ports on another
431 435 machine, to which you have SSH access.
432 436
433 437 In simple cases, IPython's tools can forward ports over ssh by simply adding the
434 438 ``--ssh=remote`` argument to the usual ``--existing...`` set of flags for connecting
435 439 to a running kernel, after copying the JSON connection file (or its contents) to
436 440 the second computer.
437 441
438 442 .. warning::
439 443
440 444 Using SSH tunnels does *not* increase localhost security. In fact, when
441 445 tunneling from one machine to another *both* machines have open
442 446 ports on localhost available for connections to the kernel.
443 447
444 448 There are two primary models for using SSH tunnels with IPython. The first
445 449 is to have the Kernel listen only on localhost, and connect to it from
446 450 another machine on the same LAN.
447 451
448 452 First, let's start a kernel on machine **worker**, listening only
449 453 on loopback::
450 454
451 455 user@worker $> ipython kernel
452 456 [IPKernelApp] To connect another client to this kernel, use:
453 457 [IPKernelApp] --existing kernel-12345.json
454 458
455 459 In this case, the IP that you would connect
456 460 to would still be 127.0.0.1, but you want to specify the additional ``--ssh`` argument
457 461 with the hostname of the kernel (in this example, it's 'worker')::
458 462
459 463 user@client $> ipython qtconsole --ssh=worker --existing /path/to/kernel-12345.json
460 464
461 465 Which will write a new connection file with the forwarded ports, so you can reuse them::
462 466
463 467 [IPythonQtConsoleApp] To connect another client via this tunnel, use:
464 468 [IPythonQtConsoleApp] --existing kernel-12345-ssh.json
465 469
466 470 Note again that this opens ports on the *client* machine that point to your kernel.
467 471
468 472 .. note::
469 473
470 474 the ssh argument is simply passed to openssh, so it can be fully specified ``user@host:port``
471 475 but it will also respect your aliases, etc. in :file:`.ssh/config` if you have any.
472 476
473 477 The second pattern is for connecting to a machine behind a firewall across the internet
474 478 (or otherwise wide network). This time, we have a machine **login** that you have ssh access
475 479 to, which can see **kernel**, but **client** is on another network. The important difference
476 480 now is that **client** can see **login**, but *not* **worker**. So we need to forward ports from
477 481 client to worker *via* login. This means that the kernel must be started listening
478 482 on external interfaces, so that its ports are visible to `login`::
479 483
480 484 user@worker $> ipython kernel --ip=0.0.0.0
481 485 [IPKernelApp] To connect another client to this kernel, use:
482 486 [IPKernelApp] --existing kernel-12345.json
483 487
484 488 Which we can connect to from the client with::
485 489
486 490 user@client $> ipython qtconsole --ssh=login --ip=192.168.1.123 --existing /path/to/kernel-12345.json
487 491
488 492 .. note::
489 493
490 494 The IP here is the address of worker as seen from *login*, and need only be specified if
491 495 the kernel used the ambiguous 0.0.0.0 (all interfaces) address. If it had used
492 496 192.168.1.123 to start with, it would not be needed.
493 497
494 498
495 499 Manual SSH tunnels
496 500 ------------------
497 501
498 502 It's possible that IPython's ssh helper functions won't work for you, for various
499 503 reasons. You can still connect to remote machines, as long as you set up the tunnels
500 504 yourself. The basic format of forwarding a local port to a remote one is::
501 505
502 506 [client] $> ssh <server> <localport>:<remoteip>:<remoteport> -f -N
503 507
504 508 This will forward local connections to **localport** on client to **remoteip:remoteport**
505 509 *via* **server**. Note that remoteip is interpreted relative to *server*, not the client.
506 510 So if you have direct ssh access to the machine to which you want to forward connections,
507 511 then the server *is* the remote machine, and remoteip should be server's IP as seen from the
508 512 server itself, i.e. 127.0.0.1. Thus, to forward local port 12345 to remote port 54321 on
509 513 a machine you can see, do::
510 514
511 515 [client] $> ssh machine 12345:127.0.0.1:54321 -f -N
512 516
513 517 But if your target is actually on a LAN at 192.168.1.123, behind another machine called **login**,
514 518 then you would do::
515 519
516 520 [client] $> ssh login 12345:192.168.1.16:54321 -f -N
517 521
518 522 The ``-f -N`` on the end are flags that tell ssh to run in the background,
519 523 and don't actually run any commands beyond creating the tunnel.
520 524
521 525 .. seealso::
522 526
523 527 A short discussion of ssh tunnels: http://www.revsys.com/writings/quicktips/ssh-tunnel.html
524 528
525 529
526 530
527 531 Stopping Kernels and Consoles
528 532 *****************************
529 533
530 534 Since there can be many consoles per kernel, the shutdown mechanism and dialog
531 535 are probably more complicated than you are used to. Since you don't always want
532 536 to shutdown a kernel when you close a window, you are given the option to just
533 537 close the console window or also close the Kernel and *all other windows*. Note
534 538 that this only refers to all other *local* windows, as remote Consoles are not
535 539 allowed to shutdown the kernel, and shutdowns do not close Remote consoles (to
536 540 allow for saving, etc.).
537 541
538 542 Rules:
539 543
540 544 * Restarting the kernel automatically clears all *local* Consoles, and prompts remote
541 545 Consoles about the reset.
542 546 * Shutdown closes all *local* Consoles, and notifies remotes that
543 547 the Kernel has been shutdown.
544 548 * Remote Consoles may not restart or shutdown the kernel.
545 549
546 550 Qt and the QtConsole
547 551 ====================
548 552
549 553 An important part of working with the QtConsole when you are writing your own
550 554 Qt code is to remember that user code (in the kernel) is *not* in the same
551 555 process as the frontend. This means that there is not necessarily any Qt code
552 556 running in the kernel, and under most normal circumstances there isn't. If,
553 557 however, you specify ``--matplotlib qt`` at the command-line, then there *will* be a
554 558 :class:`QCoreApplication` instance running in the kernel process along with
555 559 user-code. To get a reference to this application, do:
556 560
557 561 .. sourcecode:: python
558 562
559 563 from PyQt4 import QtCore
560 564 app = QtCore.QCoreApplication.instance()
561 565 # app will be None if there is no such instance
562 566
563 567 A common problem listed in the PyQt4 Gotchas_ is the fact that Python's garbage
564 568 collection will destroy Qt objects (Windows, etc.) once there is no longer a
565 569 Python reference to them, so you have to hold on to them. For instance, in:
566 570
567 571 .. sourcecode:: python
568 572
569 573 def make_window():
570 574 win = QtGui.QMainWindow()
571 575
572 576 def make_and_return_window():
573 577 win = QtGui.QMainWindow()
574 578 return win
575 579
576 580 :func:`make_window` will never draw a window, because garbage collection will
577 581 destroy it before it is drawn, whereas :func:`make_and_return_window` lets the
578 582 caller decide when the window object should be destroyed. If, as a developer,
579 583 you know that you always want your objects to last as long as the process, you
580 584 can attach them to the QApplication instance itself:
581 585
582 586 .. sourcecode:: python
583 587
584 588 # do this just once:
585 589 app = QtCore.QCoreApplication.instance()
586 590 app.references = set()
587 591 # then when you create Windows, add them to the set
588 592 def make_window():
589 593 win = QtGui.QMainWindow()
590 594 app.references.add(win)
591 595
592 596 Now the QApplication itself holds a reference to ``win``, so it will never be
593 597 garbage collected until the application itself is destroyed.
594 598
595 599 .. _Gotchas: http://www.riverbankcomputing.co.uk/static/Docs/PyQt4/html/gotchas.html#garbage-collection
596 600
597 601 Embedding the QtConsole in a Qt application
598 602 *******************************************
599 603
600 604 In order to make the QtConsole available to an external Qt GUI application (just as
601 605 :func:`IPython.embed` enables one to embed a terminal session of IPython in a
602 606 command-line application), there are a few options:
603 607
604 608 * First start IPython, and then start the external Qt application from IPython,
605 609 as described above. Effectively, this embeds your application in IPython
606 610 rather than the other way round.
607 611
608 612 * Use :class:`IPython.qt.console.rich_ipython_widget.RichIPythonWidget` in your
609 613 Qt application. This will embed the console widget in your GUI and start the
610 614 kernel in a separate process, so code typed into the console cannot access
611 615 objects in your application.
612 616
613 617 * Start a standard IPython kernel in the process of the external Qt
614 618 application. See :file:`examples/lib/ipkernel_qtapp.py` for an example. Due
615 619 to IPython's two-process model, the QtConsole itself will live in another
616 620 process with its own QApplication, and thus cannot be embedded in the main
617 621 GUI.
618 622
619 623 * Start a special IPython kernel, the
620 624 :class:`IPython.kernel.inprocess.ipkernel.InProcessKernel`, that allows a
621 625 QtConsole in the same process. See :file:`examples/inprocess/embedded_qtconsole.py`
622 626 for an example. While the QtConsole can now be embedded in the main GUI, one
623 627 cannot connect to the kernel from other consoles as there are no real ZMQ
624 628 sockets anymore.
625 629
626 630 Regressions
627 631 ===========
628 632
629 633 There are some features, where the qt console lags behind the Terminal
630 634 frontend:
631 635
632 636 * !cmd input: Due to our use of pexpect, we cannot pass input to subprocesses
633 637 launched using the '!' escape, so you should never call a command that
634 638 requires interactive input. For such cases, use the terminal IPython. This
635 639 will not be fixed, as abandoning pexpect would significantly degrade the
636 640 console experience.
637 641
638 642 .. _PyQt: http://www.riverbankcomputing.co.uk/software/pyqt/download
639 643 .. _pygments: http://pygments.org/
General Comments 0
You need to be logged in to leave comments. Login now