IPython - 从小部件运行以下所有单元格

21

我正在尝试使用多选小部件让用户从国家列表中进行选择,然后有一个小部件按钮,当点击时,运行下方的所有单元格。

这将显示列表。

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

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

我希望能够运行下方所有单元格的代码:

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

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

但是我找不到“运行下面的所有单元格”的钩子。

谢谢。

4个回答

25

如果我理解正确,你可以通过JavaScript来实现。

请参考以下代码:

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

将执行活动单元格下方的所有单元格,因此对于您的按钮,它可能类似于:

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)

如果这是你所需要的,请告诉我。


1
这个功能很好,但是现在我已经测试过了,当点击按钮时,多选框的状态会丢失,我无法捕获值。似乎它重新执行了包含多选框和按钮的单元格? - colster
好的,明白了。使用w.selected_labels=(())来清除选择。 - colster
3
我遇到了与 @colser 相同的问题——由于“执行下面的单元格”重新执行当前单元格,所有其他小部件的状态都会丢失。基本上,我正在尝试构建一个表单 UI,向用户展示一些输入和底部的“计算”按钮。你是如何解决这个问题的?你有样例笔记本吗? - volodymyr
1
在我的情况下,我只是将代码添加到一个孤立的单元格中,该单元格仅包含@kikocorreoso的代码。 - toto_tico
3
这里的任何解决方案对我都无效。使用此代码,Javascript无法执行任何操作:Javascript('IPython.notebook.execute_cells_below()') - quadrismegistus
显示剩余3条评论

16
运行当前单元格下方的所有单元格,而不执行拥有此按钮的单元格:
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)

这使当前单元格也可以提示其他输入,并保留这些输入的值。 IPython.notebook.execute_cells_below()将执行当前单元格,如果该单元格中还显示了其他输入,则它们将获取它们的默认值。


嘿,Michael,有没有办法使其适应仅运行直接下方的单元格而不是所有单元格?我一直在尝试,但无法弄清楚如何只运行下面的单元格。 - Brian Keith
我尝试过 display(Javascript('IPython.notebook.execute_cell_range(IPython.notebook.get_selected_index()+1, IPython.notebook.get_selected_index()+2)')) 但它会因某种原因运行多个单元格,我不确定为什么。 - Brian Keith

1
你已经收到了一些非常好的建议,但我想提到一个与HTML相当灵活的选项:

代码:

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>''')

这将为您生成一个按钮,以运行笔记本下方的所有单元格。
使用此方法的奖励功能是,如果您正在使用Dunovank在github上的Jupyter主题https://github.com/dunovank/jupyter-themes,则您的按钮布局将遵循主题选择。
我尝试附加截图,但我还不能这样做。

0
如果您想运行下面的单元格,只需按下按钮即可 这就可以解决问题!
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)

请查看“完全基于代码的答案解释” 。虽然这可能在技术上是正确的,但它没有解释为什么它可以解决问题或者为什么应该被选为最佳答案。我们应该在帮助解决问题的同时进行教育。 - the Tin Man

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接