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