diff --git a/IPython/html/widgets/interaction.py b/IPython/html/widgets/interaction.py
index 1b59de8..93b6e7c 100644
--- a/IPython/html/widgets/interaction.py
+++ b/IPython/html/widgets/interaction.py
@@ -23,7 +23,7 @@ from inspect import getcallargs
from IPython.core.getipython import get_ipython
from IPython.html.widgets import (Widget, TextWidget,
FloatSliderWidget, IntSliderWidget, CheckboxWidget, DropdownWidget,
- ContainerWidget, DOMWidget)
+ ContainerWidget, DOMWidget, ButtonWidget)
from IPython.display import display, clear_output
from IPython.utils.py3compat import string_types, unicode_type
from IPython.utils.traitlets import HasTraits, Any, Unicode
@@ -114,7 +114,7 @@ def _widget_from_abbrev(abbrev, default=empty):
"""Build a Widget instance given an abbreviation or Widget."""
if isinstance(abbrev, Widget) or isinstance(abbrev, fixed):
return abbrev
-
+
widget = _widget_abbrev(abbrev)
if default is not empty and isinstance(abbrev, (list, tuple, dict)):
# if it's not a single-value abbreviation,
@@ -175,6 +175,7 @@ def interactive(__interact_f, **kwargs):
"""Build a group of widgets to interact with a function."""
f = __interact_f
co = kwargs.pop('clear_output', True)
+ on_demand = kwargs.pop('on_demand', False)
kwargs_widgets = []
container = ContainerWidget()
container.result = None
@@ -194,10 +195,15 @@ def interactive(__interact_f, **kwargs):
# so that traitlets notices the update. We skip any objects (such as fixed) that
# are not DOMWidgets.
c = [w for w in kwargs_widgets if isinstance(w, DOMWidget)]
+
+ # If we are only to run the function on demand, add a button to request this
+ if on_demand:
+ on_demand_button = ButtonWidget(description="Run %s" % f.__name__)
+ c.append(on_demand_button)
container.children = c
# Build the callback
- def call_f(name, old, new):
+ def call_f(name=None, old=None, new=None):
container.kwargs = {}
for widget in kwargs_widgets:
value = widget.value
@@ -214,16 +220,22 @@ def interactive(__interact_f, **kwargs):
ip.showtraceback()
# Wire up the widgets
- for widget in kwargs_widgets:
- widget.on_trait_change(call_f, 'value')
+ # If we are doing on demand running, the callback is only triggered by the button
+ # Otherwise, it is triggered for every trait change received
+ # On-demand running also suppresses running the fucntion with the initial parameters
+ if on_demand:
+ on_demand_button.on_click(call_f)
+ else:
+ for widget in kwargs_widgets:
+ widget.on_trait_change(call_f, 'value')
- container.on_displayed(lambda _: call_f(None, None, None))
+ container.on_displayed(lambda _: call_f(None, None, None))
return container
def interact(__interact_f=None, **kwargs):
"""interact(f, **kwargs)
-
+
Interact with a function using widgets."""
# positional arg support in: https://gist.github.com/8851331
if __interact_f is not None: