##// 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 from IPython.core.getipython import get_ipython
23 from IPython.core.getipython import get_ipython
24 from IPython.html.widgets import (Widget, TextWidget,
24 from IPython.html.widgets import (Widget, TextWidget,
25 FloatSliderWidget, IntSliderWidget, CheckboxWidget, DropdownWidget,
25 FloatSliderWidget, IntSliderWidget, CheckboxWidget, DropdownWidget,
26 ContainerWidget, DOMWidget)
26 ContainerWidget, DOMWidget, ButtonWidget)
27 from IPython.display import display, clear_output
27 from IPython.display import display, clear_output
28 from IPython.utils.py3compat import string_types, unicode_type
28 from IPython.utils.py3compat import string_types, unicode_type
29 from IPython.utils.traitlets import HasTraits, Any, Unicode
29 from IPython.utils.traitlets import HasTraits, Any, Unicode
@@ -114,7 +114,7 b' def _widget_from_abbrev(abbrev, default=empty):'
114 """Build a Widget instance given an abbreviation or Widget."""
114 """Build a Widget instance given an abbreviation or Widget."""
115 if isinstance(abbrev, Widget) or isinstance(abbrev, fixed):
115 if isinstance(abbrev, Widget) or isinstance(abbrev, fixed):
116 return abbrev
116 return abbrev
117
117
118 widget = _widget_abbrev(abbrev)
118 widget = _widget_abbrev(abbrev)
119 if default is not empty and isinstance(abbrev, (list, tuple, dict)):
119 if default is not empty and isinstance(abbrev, (list, tuple, dict)):
120 # if it's not a single-value abbreviation,
120 # if it's not a single-value abbreviation,
@@ -175,6 +175,7 b' def interactive(__interact_f, **kwargs):'
175 """Build a group of widgets to interact with a function."""
175 """Build a group of widgets to interact with a function."""
176 f = __interact_f
176 f = __interact_f
177 co = kwargs.pop('clear_output', True)
177 co = kwargs.pop('clear_output', True)
178 on_demand = kwargs.pop('on_demand', False)
178 kwargs_widgets = []
179 kwargs_widgets = []
179 container = ContainerWidget()
180 container = ContainerWidget()
180 container.result = None
181 container.result = None
@@ -194,10 +195,15 b' def interactive(__interact_f, **kwargs):'
194 # so that traitlets notices the update. We skip any objects (such as fixed) that
195 # so that traitlets notices the update. We skip any objects (such as fixed) that
195 # are not DOMWidgets.
196 # are not DOMWidgets.
196 c = [w for w in kwargs_widgets if isinstance(w, DOMWidget)]
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 container.children = c
203 container.children = c
198
204
199 # Build the callback
205 # Build the callback
200 def call_f(name, old, new):
206 def call_f(name=None, old=None, new=None):
201 container.kwargs = {}
207 container.kwargs = {}
202 for widget in kwargs_widgets:
208 for widget in kwargs_widgets:
203 value = widget.value
209 value = widget.value
@@ -214,16 +220,22 b' def interactive(__interact_f, **kwargs):'
214 ip.showtraceback()
220 ip.showtraceback()
215
221
216 # Wire up the widgets
222 # Wire up the widgets
217 for widget in kwargs_widgets:
223 # If we are doing on demand running, the callback is only triggered by the button
218 widget.on_trait_change(call_f, 'value')
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 return container
234 return container
223
235
224 def interact(__interact_f=None, **kwargs):
236 def interact(__interact_f=None, **kwargs):
225 """interact(f, **kwargs)
237 """interact(f, **kwargs)
226
238
227 Interact with a function using widgets."""
239 Interact with a function using widgets."""
228 # positional arg support in: https://gist.github.com/8851331
240 # positional arg support in: https://gist.github.com/8851331
229 if __interact_f is not None:
241 if __interact_f is not None:
General Comments 0
You need to be logged in to leave comments. Login now