Search code examples
pythonjupyter-notebookipywidgets

How to extract text from ipwidgets Text widget


The documentation for this is very cumbersome and time-consuming. I need a simple basic Hello World example to extract a simple text from a text box

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

dossier_number_widget = widgets.Text(
    value='EP23210283',
    placeholder='EP23210283',
    description='Dossier Number:',
    disabled=False,
    continuous_update=True
)
display(dossier_number_widget)

def callback(wdgt):
    print(wdgt) # it doesn't print
    display(wdgt) # it doesn't display
    print(wdgt.value) # it doesn't print
    display(wdgt.value) # it doesn't display

dossier_number_widget.observe(callback, 'value')

It's not working, what am I doing wrong?

Other examples here on SO mention on_submit but this method is deprecated

I tried with a button with no result, it simply doesn't print the result

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

submit_button=widgets.Button(description='Submit',button_style='success')
dossier_number_widget = widgets.Text(
    value='EP23210283',
    placeholder='EP23210283',
    description='Dossier Number:',
    disabled=False,
    continuous_update=False
)

def on_button_clicked(wdgt):
    print(dossier_number_widget.value) # it doesn't print
    display(dossier_number_widget.value) # it doesn't display

submit_button.on_click(on_button_clicked)

display(dossier_number_widget, submit_button)

Solution

  • Here is an example of extracting text from a text widget and reacting to it to give the user feedback:

    from ipywidgets import interact, interactive, fixed, interact_manual
    import ipywidgets as widgets
    
    text_input = widgets.Text(
            value="",
            description="Enter text here:",
            style={"description_width": "initial"},
            layout=widgets.Layout(width='70%'), 
        )
    
    def f(x):
        if "Hello World" in x:
            return "WHAT YOU TYPED CONTAINS MY FAVORITE PHRASE! YOU DID IT!!"
        elif x != '':
            return (f"I see you typed: {x}. You haven't typed my favorite phrase yet.")
        else:
            return x
    
    interact(f, x=text_input);
    

    It mainly is adapted from a code block I shared here in reply to 'Jupyter Widgets Formatting' and the ipywidgets documentation on interact().

    You'll see that it doesn't build on your example that you stated the following about, "It's not working, what am I doing wrong?". Note, that your post doesn't include what you expected to happen or how you wanted to extract and do something leaving a lot to the imagination and making it difficult to give reasonable answers based on your provided code. Please read How do I ask a good question? for next time. Especially the sections and links therein under sections about 'on-topic and suitable' and 'Help others reproduce the problem'.

    Additional resources

    For additional help, see:

    Why the OP's use of print(wdgt) & display(widgt) don't show anything (I think)

    In the first code block by the OP, there's the following:

    def callback(wdgt):
        print(wdgt) # it doesn't print
        display(wdgt) # it doesn't display
        print(wdgt.value) # it doesn't print
        display(wdgt.value) # it doesn't display
    

    And the comments stress that the OP isn't seeing that print or display.
    OP might have chosen to use JupyterLab and noted in the 'Log Console' that those print and displays did send output there, and not to current Jupyter's output area. (More about this below.)
    I think that was basically the same issue as this post 'ipywidgets buttons not responding', and my answer there should offer insight. Essentially the issue in summary is, "in modern ipywidgets and Jupyter you have to be explicit in how you connect up the output being generated to the output area of the cell."
    interact() use in my example makes things easier in this case; however, if the OP did want to continue developing the code in the first block that could be done by adding in handling of the output. The resources at the links in this section could serve as a guide to implementing that in that code.

    I mention above JupyterLab is better for developing with ipywidgets these days, and you may want to read more about that in the 'Details' section for a related topic here.


    Further refined example with interact()

    You may note that the text has quotes around it that look weird due to the string representation returned to the interact function getting displayed. That situation was left in the code block above to keep the code simpler since the question was really concerned only with extracting content from the Text widget. Things can be made less rough around the edges by returning an HTML widget that will show in the output area of Jupter better, based on here.

    from ipywidgets import interact, interactive, fixed, interact_manual
    import ipywidgets as widgets
    
    text_input = widgets.Text(
            value="",
            description="Enter text here:",
            style={"description_width": "initial"},
            layout=widgets.Layout(width='70%'), 
        )
    
    def f(x):
        if "Hello World" in x:
            return widgets.HTML("WHAT YOU TYPED CONTAINS MY FAVORITE PHRASE! YOU DID IT!!")
        elif x != '':
            return widgets.HTML(f"I see you typed: '{x}'. You haven't typed my favorite phrase yet.")
        else:
            return widgets.HTML(x)
    
    interact(f, x=text_input);