2

I'm sorry if this question has already been answered, but I couldn't find anything on here (except this one which hasn't been answered: link and one that doesn't quite answer the question i'm asking link

I'm creating a button with ipywidgets, but the script doesn't wait for the button to be clicked. Here's a sample of the code/what I'm trying to achieve:

button = widgets.Button(description = "Click")
output = widgets.Output()
display(button, output)

def on_button_clicked(b):
     with output:
     print("button clicked")

button.on_click(on_button_clicked)
print("Python is ignoring you")

If I run this, I'll just get "Python is ignoring you" before I click the button. I want it to display the button, wait for the person to click it, and only then execute the rest ("Python is ignoring you").

Does anyone have an idea of how I can make python wait for the button to be clicked?

Would appreciate any help! Thanks

1
  • If you have lots more code to run, then you will need to place all of this code inside functions. The button.on_click just makes the connection between what will happen if you do click the button. There is no way to suspend the body of code being run. Commented Sep 8, 2020 at 8:21

2 Answers 2

3

We need to explicitly poll the UI events

There's a neat little library called jupyter-ui-poll which handles exactly this use case! The rest of the button setup you have can stay the same. We just need to wrap a pollable scope around the loop like so:

from jupyter_ui_poll import ui_events
import time
...
clicked = False
def on_button_clicked(b):
    global clicked
    clicked = True
    with output:
        print("button clicked")

button.on_click(on_button_clicked)

with ui_events() as poll:
    while not clicked:
        poll(10) # poll queued UI events including button
        time.sleep(1) # wait for 1 second before checking again
print('python waited for the button click')

The issue is that the IPython kernel executes a queue of events, but there's one queue for both UI event callbacks and cell execution. So once it's busy working on a cell, UI events don't get processed. jupyter-ui-poll temporarily (inside the scope) adjusts this queueing behaviour to allow for explicit polling.

Sign up to request clarification or add additional context in comments.

Comments

1

I never used the ipywidgets, but the problem is on the last line

you're telling python to print "Python is ignoring you" and python is doing it.

It will not wait for the user to click the button,

because the print statement is out the function "on_button_clicked".(or any)

So just Put it in the function. (That print Statement)

1 Comment

Thanks! For now I just put a random input command that makes you press enter after the button click. Good enough for what I'm trying to achieve :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.