IPython Notebook:如何通过 JavaScript 编程方式触发一个单元格?

8

我最近玩了几天IPython笔记本,我非常喜欢它!但是,现在我需要做一些稍微高级的事情:

我有一个Markdown单元格;其中包含一个HTML输入和按钮,以及附加到按钮的一些JavaScript,将输入内容传递给python内核。以下是该单元格:

<h3>Use JS to pass DOM info to Python kernel: </h3>
<input id='testinput' value='FragmentId'></input>
<button id='testComms' onclick='JS2PY()'>:D</button>

<script type="text/javascript">    
    function JS2PY(){
        var input = document.getElementById('testinput').value,
            kernel = IPython.notebook.kernel;

        kernel.execute('testVar = "' + input + '"');
    }
</script>

使用得心应手!接下来,我有一个Python代码单元格;它执行一些ROOT操作,并基于从上面的单元格中注入到Python内核的任何值生成图表。这是Python单元格:

def testfunc():
    from ROOT import TH1, TFile, TTree
    import rootnotes, numpy

    c2 = rootnotes.canvas("treeData", (600,400))

    testfile = TFile("fragment27422_000.root")
    testtree = testfile.Get("FragmentTree")

    buff = numpy.zeros(1, dtype=float)

    testtree.Branch(testVar, buff)

    testtree.Draw(testVar)
    return c2

testfunc()

如果我手动运行单元格,也没有问题 - 太好了! 但是我真正想要的是,当我在上面的markdown单元格中点击那个按钮后,这个python单元格会自动运行,并推广testVar变量。抱歉并提前感谢 - 这只是我学习Python的第二天,所以可能非常简单。

2个回答

10

解决方法/解决方案:可以调用其他单元格中定义的Python函数,通过回调从JavaScript和Python内核之间实现往返,而不是直接触发其他单元格。可以使用IPython.notebook.kernel.execute实现,类似于这个代码单元格:

```python # 在当前单元格中执行以下代码 from IPython.display import display, Javascript
def callback(output): # 处理程序返回的输出结果 pass
def execute_this_cell(): # 调用其他单元格中定义的 Python 函数 code = '''function_that_calls_python_function()''' display(Javascript(code, callback=callback))
execute_this_cell() ```
%%HTML

<div id='testwrap'>
<input id='varname'></input>
<img id='imgtarget'></img>
<button id='fetchplot' onclick='exec_code()'>Plot</button>
</div>

<script type="text/Javascript">
    function handle_output(out_type, out){
        document.getElementById('imgtarget').src = 'data:image/png;base64,' + out.data['image/png'];
    }

    function exec_code(){
        var kernel = IPython.notebook.kernel;
        var callbacks = {'output' : handle_output};
        kernel.execute('testVar = "' + document.getElementById('varname').value + '"');
        kernel.execute('testfunc(testVar)', callbacks, {silent:false});
    }
</script>

第一个kernel.execute从DOM将一些数据传递到内核,第二个使用回调函数处理python函数testfunc返回的任何内容(在其他单元中定义)。

感谢http://jakevdp.github.io/blog/2013/06/01/ipython-notebook-javascript-python-communication/提供此解决方案的核心思路!


0

有趣的第一个项目使用笔记本电脑(好吧,这篇文章现在有点旧了)。现在,可以像这样使用IPython.notebook.execute_cell(..)

%%HTML

<h3>Select an Experiment</h3>
<input id='input' value='my input var'></input>
<button id='testComms' onclick='JS2PY()'>:D</button>

<script type="text/javascript">    
    function JS2PY() {
        const { value } = document.getElementById('input');
        const pycode = `testVar = '${value}'`;
        const { notebook } = IPython;
        const { kernel } = notebook;
        kernel.execute(pycode);
        // run cell using `testVar`
        notebook.select_next();
        notebook.execute_cell();
    }
</script>

在上面的示例中,下一个笔记本单元格应包含您想要执行的代码。

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