Fail to wait for user action
AlexBdx opened this issue · 1 comments
I have a simple GUI in a Jupyter Notebook with two widgets: a drop down menu with 3 choices and a push button.
The desired behavior is:
- Execute the cell that contains the widgets (see code below)
- Wait (as long as needed) for the user to click on the push button
- Print the value of the drop down menu (the user's choice)
Using asyncio out of the box does not work in Jupyter Notebook because there is already an event loop running. I tried to user nest_asyncio to solve that issue, and the RunTimeError
did go away. But instead, the notebook hangs forever. When I click on the push button, nothing happens.
I saw there were issues with asyncio.Future in #22, so maybe I am missing something. Any idea how I can leverage nest_asyncio to make this work? Thanks
import nest_asyncio
nest_asyncio.apply()
from ipywidgets import Button, Dropdown, HBox
import asyncio
choices = Dropdown(options=[1, 2, 3], description='Choice')
button = Button(description="Select")
panel = HBox([choices, button])
def wait_for_change(push_button, dropdown):
future = asyncio.Future() # Make getvalue function awaitable
def getvalue(change):
future.set_result(dropdown.value)
push_button.on_click(getvalue, remove=True) # Unbind function from widget
push_button.on_click(getvalue)
return future
async def main():
user_choice = await wait_for_change(button, choices)
print(f"User selected option {user_choice}")
return user_choice
display(panel)
print("Which option would you like to choose?")
out = asyncio.run(main())
print("End of code")
import nest_asyncio
nest_asyncio.apply()
...
out = asyncio.run(main())
Using the top-level await
from IPython, these lines of code can be replaced with
out = await main()
When I try this it hangs as well, and since it's not using nest_asyncio anymore it must be something in ipywidgets itself..