21

I'm trying use a multi select widget to enable users to select from a list of countries, and then have a widget button which, when clicked, runs all the cells below.

This displays the list.

from IPython.display import display
w = widgets.SelectMultiple(

    description="Select up to five countries",
    options=dfCountries['name'].tolist()   
)
display(w)

And I want something like this to run all cells below:

def run_all(button):
    get_ipython().run_cell()

button = widgets.Button(description="Create next input")
button.on_click(run_all)
display(button)

But I can't find the hook to 'run all cells below

Thanks

colster
  • 359
  • 1
  • 3
  • 9

4 Answers4

25

If I understood correctly you could do that via js.

See the following code:

from IPython.display import Javascript
Javascript('IPython.notebook.execute_cells_below()')

Will execute all the cells below the active cell so for you button it could be something like:

from IPython.display import Javascript, display
from ipywidgets import widgets

def run_all(ev):
    display(Javascript('IPython.notebook.execute_cells_below()'))

button = widgets.Button(description="Create next input")
button.on_click(run_all)
display(button)

Let me know if this is what you need.

kikocorreoso
  • 3,999
  • 1
  • 17
  • 26
  • That's just what I was looking for. Thanks :) – colster Sep 25 '15 at 06:52
  • 1
    This works well but now that I have tested it, when the button is clicked, the state of the multi-select box is lost and I can't capture the values. It seems like it re-executes the cell that has the multi-select and the button in it? – colster Sep 25 '15 at 08:58
  • Actually seems to be that the multi-select retains state between execution. Is there a way to clear it? – colster Sep 25 '15 at 09:10
  • Ok, got it. Clear the selection with w.selected_labels=(()) – colster Sep 25 '15 at 09:20
  • 3
    I am having the same issue as @colser had - state of all other widgets are lost, since "execute_cells_below" re-executes the current cell. Basically, I am trying to build a form UI to present to the user with come inputs and "Calculate" button in the bottom. How did you fix it? Do you have a sample notebook? – volodymyr Mar 14 '16 at 13:57
  • 1
    In my case, I just added the code in an isolated cell that only has the code of @kikocorreoso – toto_tico Nov 28 '18 at 19:06
  • @kikocorreoso I got this to work for executing all cells below, but what if i want to run just the cell directly below the button? this there an equivalent of this for "run next cell"? – Brian Keith Aug 05 '20 at 14:32
  • 3
    None of the solutions here are working for me. Javascript fails to execute anything with this code: `Javascript('IPython.notebook.execute_cells_below()')` – quadrismegistus Nov 01 '20 at 10:28
16

To run all cells below the current cell without executing the cell that has this button:

from IPython.display import Javascript, display
from ipywidgets import widgets

def run_all(ev):
    display(Javascript('IPython.notebook.execute_cell_range(IPython.notebook.get_selected_index()+1, IPython.notebook.ncells())'))

button = widgets.Button(description="Run all below")
button.on_click(run_all)
display(button)

This allows the current cell to also prompt for other inputs and those input values to be preserved. IPython.notebook.execute_cells_below() will execute the current cell and if other inputs are also displayed in this cell they will get their default values.

  • Hey Michael, is there a way to adapt this to only run the cell directly below instead of all the cells? I've been playing around with this and can't figure out how to make it just run the cell below. – Brian Keith Aug 05 '20 at 14:50
  • I have tried `display(Javascript('IPython.notebook.execute_cell_range(IPython.notebook.get_selected_index()+1, IPython.notebook.get_selected_index()+2)'))` but it will run multiple sells below for some reason and I'm not sure why. – Brian Keith Aug 05 '20 at 15:05
1

You've already received some excellent suggestions, but I'd just like to mention a pretty flexible option with HTML:

Code:

from IPython.core.display import HTML
HTML('''<script> </script> <form action="javascript:IPython.notebook.execute_cells_below()"><input type="submit" id="toggleButton" value="Refresh"></form>''')

This will produce a button for you that runs all cells below in the notebook

A bonus feature with this approach is that the layout of your button will follow a theme selection if you're using Jupyter Themes from Dunovank on github https://github.com/dunovank/jupyter-themes

I tried to attach a screenshot, but I can't do that yet.

Stian
  • 73
  • 1
  • 6
0

If you are looking to run just the cell below the button This will do the trick!

from IPython.display import Javascript, display
from ipywidgets import widgets

def run_all(ev):
    display(Javascript('IPython.notebook.execute_cell_range(IPython.notebook.get_selected_index()+1, IPython.notebook.get_selected_index()+2)'))

button = widgets.Button(description="Run The Next Cell")

button.on_click(run_all)
display(button)
mronevsall
  • 29
  • 5
  • See "[Explaining entirely code-based answers](https://meta.stackoverflow.com/q/392712/128421)". While this might be technically correct it doesn't explain why it solves the problem or should be the selected answer. We should educate along with helping solve the problem. – the Tin Man Feb 21 '22 at 20:40