ipython: Creating a new notebook cell from within a widget does not work.

While testing the new widget framework, I expected that I could create new cell in the notebook clicking a widget. (The underlying idea is to propose a widget that helps creating plotting python code by selecting data interactively.) Here is a minimal piece of code that reveal the problem:

from IPython.html import widgets
from IPython.display import display

def create(button):
    get_ipython().set_next_input('print "test"')

button = widgets.ButtonWidget(description="Create next input")
button.on_click(create)
display(button)

Execute this code in a notebook cell, click the “Create next input” button. I would expect a new cell to appear but it does not. (Using the latest head from master)

About this issue

  • Original URL
  • State: closed
  • Created 10 years ago
  • Reactions: 2
  • Comments: 26 (10 by maintainers)

Most upvoted comments

Hi @davidtrem ,

I did not close this because it was fixed, because it is not fixed yet. I closed this because it was part of a bigger problem - see #5006.

I whipped up a quick function that will do what you want:

import base64
from IPython.display import Javascript, display
from IPython.utils.py3compat import str_to_bytes, bytes_to_str
def create_code_cell(code='', where='below'):
    """Create a code cell in the IPython Notebook.

    Parameters
    code: unicode
        Code to fill the new code cell with.
    where: unicode
        Where to add the new code cell.
        Possible values include:
            at_bottom
            above
            below"""
    encoded_code = bytes_to_str(base64.b64encode(str_to_bytes(code)))
    display(Javascript("""
        var code = IPython.notebook.insert_cell_{0}('code');
        code.set_text(atob("{1}"));
    """.format(where, encoded_code)))

The following shows how this can be used with a button widget:

from IPython.html.widgets import *
def on_click(button):
    create_code_cell('print("Hello world!")')
button = ButtonWidget(description="Show hello world code")
button.on_click(on_click)
display(button)

I know this is much uglier, when #5006 is addressed completely, you should be able to use the built-in API you referenced.