##// END OF EJS Templates
Merge pull request #10881 from JeremySikes73/doc...
Thomas Kluyver -
r24030:0920f3a1 merge
parent child Browse files
Show More
@@ -1,99 +1,99 b''
1 .. _events:
1 .. _events:
2 .. _callbacks:
2 .. _callbacks:
3
3
4 ==============
4 ==============
5 IPython Events
5 IPython Events
6 ==============
6 ==============
7
7
8 Extension code can register callbacks functions which will be called on specific
8 Extension code can register callbacks functions which will be called on specific
9 events within the IPython code. You can see the current list of available
9 events within the IPython code. You can see the current list of available
10 callbacks, and the parameters that will be passed with each, in the callback
10 callbacks, and the parameters that will be passed with each, in the callback
11 prototype functions defined in :mod:`IPython.core.callbacks`.
11 prototype functions defined in :mod:`IPython.core.events`.
12
12
13 To register callbacks, use :meth:`IPython.core.events.EventManager.register`.
13 To register callbacks, use :meth:`IPython.core.events.EventManager.register`.
14 For example::
14 For example::
15
15
16 class VarWatcher(object):
16 class VarWatcher(object):
17 def __init__(self, ip):
17 def __init__(self, ip):
18 self.shell = ip
18 self.shell = ip
19 self.last_x = None
19 self.last_x = None
20
20
21 def pre_execute(self):
21 def pre_execute(self):
22 self.last_x = self.shell.user_ns.get('x', None)
22 self.last_x = self.shell.user_ns.get('x', None)
23
23
24 def pre_run_cell(self, info):
24 def pre_run_cell(self, info):
25 print('Cell code: "%s"' % info.raw_cell)
25 print('Cell code: "%s"' % info.raw_cell)
26
26
27 def post_execute(self):
27 def post_execute(self):
28 if self.shell.user_ns.get('x', None) != self.last_x:
28 if self.shell.user_ns.get('x', None) != self.last_x:
29 print("x changed!")
29 print("x changed!")
30
30
31 def post_run_cell(self, result):
31 def post_run_cell(self, result):
32 print('Cell code: "%s"' % result.info.raw_cell)
32 print('Cell code: "%s"' % result.info.raw_cell)
33 if result.error_before_exec:
33 if result.error_before_exec:
34 print('Error before execution: %s' % result.error_before_exec)
34 print('Error before execution: %s' % result.error_before_exec)
35
35
36 def load_ipython_extension(ip):
36 def load_ipython_extension(ip):
37 vw = VarWatcher(ip)
37 vw = VarWatcher(ip)
38 ip.events.register('pre_execute', vw.pre_execute)
38 ip.events.register('pre_execute', vw.pre_execute)
39 ip.events.register('pre_run_cell', vw.pre_run_cell)
39 ip.events.register('pre_run_cell', vw.pre_run_cell)
40 ip.events.register('post_execute', vw.post_execute)
40 ip.events.register('post_execute', vw.post_execute)
41 ip.events.register('post_run_cell', vw.post_run_cell)
41 ip.events.register('post_run_cell', vw.post_run_cell)
42
42
43
43
44 Events
44 Events
45 ======
45 ======
46
46
47 These are the events IPython will emit. Callbacks will be passed no arguments, unless otherwise specified.
47 These are the events IPython will emit. Callbacks will be passed no arguments, unless otherwise specified.
48
48
49 shell_initialized
49 shell_initialized
50 -----------------
50 -----------------
51
51
52 .. code-block:: python
52 .. code-block:: python
53
53
54 def shell_initialized(ipython):
54 def shell_initialized(ipython):
55 ...
55 ...
56
56
57 This event is triggered only once, at the end of setting up IPython.
57 This event is triggered only once, at the end of setting up IPython.
58 Extensions registered to load by default as part of configuration can use this to execute code to finalize setup.
58 Extensions registered to load by default as part of configuration can use this to execute code to finalize setup.
59 Callbacks will be passed the InteractiveShell instance.
59 Callbacks will be passed the InteractiveShell instance.
60
60
61 pre_run_cell
61 pre_run_cell
62 ------------
62 ------------
63
63
64 ``pre_run_cell`` fires prior to interactive execution (e.g. a cell in a notebook).
64 ``pre_run_cell`` fires prior to interactive execution (e.g. a cell in a notebook).
65 It can be used to note the state prior to execution, and keep track of changes.
65 It can be used to note the state prior to execution, and keep track of changes.
66 An object containing information used for the code execution is provided as an argument.
66 An object containing information used for the code execution is provided as an argument.
67
67
68 pre_execute
68 pre_execute
69 -----------
69 -----------
70
70
71 ``pre_execute`` is like ``pre_run_cell``, but is triggered prior to *any* execution.
71 ``pre_execute`` is like ``pre_run_cell``, but is triggered prior to *any* execution.
72 Sometimes code can be executed by libraries, etc. which
72 Sometimes code can be executed by libraries, etc. which
73 skipping the history/display mechanisms, in which cases ``pre_run_cell`` will not fire.
73 skipping the history/display mechanisms, in which cases ``pre_run_cell`` will not fire.
74
74
75 post_run_cell
75 post_run_cell
76 -------------
76 -------------
77
77
78 ``post_run_cell`` runs after interactive execution (e.g. a cell in a notebook).
78 ``post_run_cell`` runs after interactive execution (e.g. a cell in a notebook).
79 It can be used to cleanup or notify or perform operations on any side effects produced during execution.
79 It can be used to cleanup or notify or perform operations on any side effects produced during execution.
80 For instance, the inline matplotlib backend uses this event to display any figures created but not explicitly displayed during the course of the cell.
80 For instance, the inline matplotlib backend uses this event to display any figures created but not explicitly displayed during the course of the cell.
81 The object which will be returned as the execution result is provided as an
81 The object which will be returned as the execution result is provided as an
82 argument.
82 argument.
83
83
84 post_execute
84 post_execute
85 ------------
85 ------------
86
86
87 The same as ``pre_execute``, ``post_execute`` is like ``post_run_cell``,
87 The same as ``pre_execute``, ``post_execute`` is like ``post_run_cell``,
88 but fires for *all* executions, not just interactive ones.
88 but fires for *all* executions, not just interactive ones.
89
89
90
90
91 .. seealso::
91 .. seealso::
92
92
93 Module :mod:`IPython.core.hooks`
93 Module :mod:`IPython.core.hooks`
94 The older 'hooks' system allows end users to customise some parts of
94 The older 'hooks' system allows end users to customise some parts of
95 IPython's behaviour.
95 IPython's behaviour.
96
96
97 :doc:`inputtransforms`
97 :doc:`inputtransforms`
98 By registering input transformers that don't change code, you can monitor
98 By registering input transformers that don't change code, you can monitor
99 what is being executed.
99 what is being executed.
@@ -1,95 +1,108 b''
1 ================================
1 ================================
2 Integrating with GUI event loops
2 Integrating with GUI event loops
3 ================================
3 ================================
4
4
5 When the user types ``%gui qt``, IPython integrates itself with the Qt event
5 When the user types ``%gui qt``, IPython integrates itself with the Qt event
6 loop, so you can use both a GUI and an interactive prompt together. IPython
6 loop, so you can use both a GUI and an interactive prompt together. IPython
7 supports a number of common GUI toolkits, but from IPython 3.0, it is possible
7 supports a number of common GUI toolkits, but from IPython 3.0, it is possible
8 to integrate other event loops without modifying IPython itself.
8 to integrate other event loops without modifying IPython itself.
9
9
10 Terminal IPython handles event loops very differently from the IPython kernel,
10 Supported event loops include ``qt4``, ``qt5``, ``gtk2``, ``gtk3``, ``wx``,
11 so different steps are needed to integrate with each.
11 ``osx`` and ``tk``. Make sure the event loop you specify matches the GUI
12 toolkit used by your own code.
12
13
13 Event loops in the terminal
14 To make IPython GUI event loop integration occur automatically at every
14 ---------------------------
15 startup, set the ``c.InteractiveShellApp.gui`` configuration key in your
16 IPython profile (see :ref:`setting_config`).
17
18 If the event loop you use is supported by IPython, turning on event loop
19 integration follows the steps just described whether you use Terminal IPython
20 or an IPython kernel.
21
22 However, the way Terminal IPython handles event loops is very different from
23 the way IPython kernel does, so if you need to integrate with a new kind of
24 event loop, different steps are needed to integrate with each.
25
26 Integrating with a new event loop in the terminal
27 -------------------------------------------------
15
28
16 .. versionchanged:: 5.0
29 .. versionchanged:: 5.0
17
30
18 There is a new API for event loop integration using prompt_toolkit.
31 There is a new API for event loop integration using prompt_toolkit.
19
32
20 In the terminal, IPython uses prompt_toolkit to prompt the user for input.
33 In the terminal, IPython uses prompt_toolkit to prompt the user for input.
21 prompt_toolkit provides hooks to integrate with an external event loop.
34 prompt_toolkit provides hooks to integrate with an external event loop.
22
35
23 To integrate an event loop, define a function which runs the GUI event loop
36 To integrate an event loop, define a function which runs the GUI event loop
24 until there is input waiting for prompt_toolkit to process. There are two ways
37 until there is input waiting for prompt_toolkit to process. There are two ways
25 to detect this condition::
38 to detect this condition::
26
39
27 # Polling for input.
40 # Polling for input.
28 def inputhook(context):
41 def inputhook(context):
29 while not context.input_is_ready():
42 while not context.input_is_ready():
30 # Replace this with the appropriate call for the event loop:
43 # Replace this with the appropriate call for the event loop:
31 iterate_loop_once()
44 iterate_loop_once()
32
45
33 # Using a file descriptor to notify the event loop to stop.
46 # Using a file descriptor to notify the event loop to stop.
34 def inputhook2(context):
47 def inputhook2(context):
35 fd = context.fileno()
48 fd = context.fileno()
36 # Replace the functions below with those for the event loop.
49 # Replace the functions below with those for the event loop.
37 add_file_reader(fd, callback=stop_the_loop)
50 add_file_reader(fd, callback=stop_the_loop)
38 run_the_loop()
51 run_the_loop()
39
52
40 Once you have defined this function, register it with IPython:
53 Once you have defined this function, register it with IPython:
41
54
42 .. currentmodule:: IPython.terminal.pt_inputhooks
55 .. currentmodule:: IPython.terminal.pt_inputhooks
43
56
44 .. function:: register(name, inputhook)
57 .. function:: register(name, inputhook)
45
58
46 Register the function *inputhook* as the event loop integration for the
59 Register the function *inputhook* as the event loop integration for the
47 GUI *name*. If ``name='foo'``, then the user can enable this integration
60 GUI *name*. If ``name='foo'``, then the user can enable this integration
48 by running ``%gui foo``.
61 by running ``%gui foo``.
49
62
50
63
51 Event loops in the kernel
64 Integrating with a new event loop in the kernel
52 -------------------------
65 -----------------------------------------------
53
66
54 The kernel runs its own event loop, so it's simpler to integrate with others.
67 The kernel runs its own event loop, so it's simpler to integrate with others.
55 IPython allows the other event loop to take control, but it must call
68 IPython allows the other event loop to take control, but it must call
56 :meth:`IPython.kernel.zmq.kernelbase.Kernel.do_one_iteration` periodically.
69 :meth:`IPython.kernel.zmq.kernelbase.Kernel.do_one_iteration` periodically.
57
70
58 To integrate with this, write a function that takes a single argument,
71 To integrate with this, write a function that takes a single argument,
59 the IPython kernel instance, arranges for your event loop to call
72 the IPython kernel instance, arranges for your event loop to call
60 ``kernel.do_one_iteration()`` at least every ``kernel._poll_interval`` seconds,
73 ``kernel.do_one_iteration()`` at least every ``kernel._poll_interval`` seconds,
61 and starts the event loop.
74 and starts the event loop.
62
75
63 Decorate this function with :func:`IPython.kernel.zmq.eventloops.register_integration`,
76 Decorate this function with :func:`IPython.kernel.zmq.eventloops.register_integration`,
64 passing in the names you wish to register it for. Here is a slightly simplified
77 passing in the names you wish to register it for. Here is a slightly simplified
65 version of the Tkinter integration already included in IPython::
78 version of the Tkinter integration already included in IPython::
66
79
67 @register_integration('tk')
80 @register_integration('tk')
68 def loop_tk(kernel):
81 def loop_tk(kernel):
69 """Start a kernel with the Tk event loop."""
82 """Start a kernel with the Tk event loop."""
70 from tkinter import Tk
83 from tkinter import Tk
71
84
72 # Tk uses milliseconds
85 # Tk uses milliseconds
73 poll_interval = int(1000*kernel._poll_interval)
86 poll_interval = int(1000*kernel._poll_interval)
74 # For Tkinter, we create a Tk object and call its withdraw method.
87 # For Tkinter, we create a Tk object and call its withdraw method.
75 class Timer(object):
88 class Timer(object):
76 def __init__(self, func):
89 def __init__(self, func):
77 self.app = Tk()
90 self.app = Tk()
78 self.app.withdraw()
91 self.app.withdraw()
79 self.func = func
92 self.func = func
80
93
81 def on_timer(self):
94 def on_timer(self):
82 self.func()
95 self.func()
83 self.app.after(poll_interval, self.on_timer)
96 self.app.after(poll_interval, self.on_timer)
84
97
85 def start(self):
98 def start(self):
86 self.on_timer() # Call it once to get things going.
99 self.on_timer() # Call it once to get things going.
87 self.app.mainloop()
100 self.app.mainloop()
88
101
89 kernel.timer = Timer(kernel.do_one_iteration)
102 kernel.timer = Timer(kernel.do_one_iteration)
90 kernel.timer.start()
103 kernel.timer.start()
91
104
92 Some event loops can go one better, and integrate checking for messages on the
105 Some event loops can go one better, and integrate checking for messages on the
93 kernel's ZMQ sockets, making the kernel more responsive than plain polling. How
106 kernel's ZMQ sockets, making the kernel more responsive than plain polling. How
94 to do this is outside the scope of this document; if you are interested, look at
107 to do this is outside the scope of this document; if you are interested, look at
95 the integration with Qt in :mod:`IPython.kernel.zmq.eventloops`.
108 the integration with Qt in :mod:`IPython.kernel.zmq.eventloops`.
General Comments 0
You need to be logged in to leave comments. Login now