##// END OF EJS Templates
Add 'on_demand' option to interact() so that long-running functions can be started only when explicitly requested
Gordon Ball -
Show More
@@ -23,7 +23,7 b' from inspect import getcallargs'
23 23 from IPython.core.getipython import get_ipython
24 24 from IPython.html.widgets import (Widget, TextWidget,
25 25 FloatSliderWidget, IntSliderWidget, CheckboxWidget, DropdownWidget,
26 ContainerWidget, DOMWidget)
26 ContainerWidget, DOMWidget, ButtonWidget)
27 27 from IPython.display import display, clear_output
28 28 from IPython.utils.py3compat import string_types, unicode_type
29 29 from IPython.utils.traitlets import HasTraits, Any, Unicode
@@ -114,7 +114,7 b' def _widget_from_abbrev(abbrev, default=empty):'
114 114 """Build a Widget instance given an abbreviation or Widget."""
115 115 if isinstance(abbrev, Widget) or isinstance(abbrev, fixed):
116 116 return abbrev
117
117
118 118 widget = _widget_abbrev(abbrev)
119 119 if default is not empty and isinstance(abbrev, (list, tuple, dict)):
120 120 # if it's not a single-value abbreviation,
@@ -175,6 +175,7 b' def interactive(__interact_f, **kwargs):'
175 175 """Build a group of widgets to interact with a function."""
176 176 f = __interact_f
177 177 co = kwargs.pop('clear_output', True)
178 on_demand = kwargs.pop('on_demand', False)
178 179 kwargs_widgets = []
179 180 container = ContainerWidget()
180 181 container.result = None
@@ -194,10 +195,15 b' def interactive(__interact_f, **kwargs):'
194 195 # so that traitlets notices the update. We skip any objects (such as fixed) that
195 196 # are not DOMWidgets.
196 197 c = [w for w in kwargs_widgets if isinstance(w, DOMWidget)]
198
199 # If we are only to run the function on demand, add a button to request this
200 if on_demand:
201 on_demand_button = ButtonWidget(description="Run %s" % f.__name__)
202 c.append(on_demand_button)
197 203 container.children = c
198 204
199 205 # Build the callback
200 def call_f(name, old, new):
206 def call_f(name=None, old=None, new=None):
201 207 container.kwargs = {}
202 208 for widget in kwargs_widgets:
203 209 value = widget.value
@@ -214,16 +220,22 b' def interactive(__interact_f, **kwargs):'
214 220 ip.showtraceback()
215 221
216 222 # Wire up the widgets
217 for widget in kwargs_widgets:
218 widget.on_trait_change(call_f, 'value')
223 # If we are doing on demand running, the callback is only triggered by the button
224 # Otherwise, it is triggered for every trait change received
225 # On-demand running also suppresses running the fucntion with the initial parameters
226 if on_demand:
227 on_demand_button.on_click(call_f)
228 else:
229 for widget in kwargs_widgets:
230 widget.on_trait_change(call_f, 'value')
219 231
220 container.on_displayed(lambda _: call_f(None, None, None))
232 container.on_displayed(lambda _: call_f(None, None, None))
221 233
222 234 return container
223 235
224 236 def interact(__interact_f=None, **kwargs):
225 237 """interact(f, **kwargs)
226
238
227 239 Interact with a function using widgets."""
228 240 # positional arg support in: https://gist.github.com/8851331
229 241 if __interact_f is not None:
General Comments 0
You need to be logged in to leave comments. Login now