1

How to create a for loop that proceeds to the next item when a Button widget is pressed? The Button description should be updated in the for loop.

In the official documentation of Asynchronous widgets, they show how to stop a for loop and then proceed to the next item when the user moves an IntSlider widget. It is mentioned that a similar result can be achieved with a Button, even though Buttons have a different interface than other widgets.

What I want is the same desired outcome of an existing question. Even though the question has an accepted answer, from the comments it is clear that the answer does not produce the desired outcome.

Enrico Gandini
  • 855
  • 5
  • 29
  • I answered my own question, but I am more than willing to accept a different answer, if better in any way: more pythonic, more concise... – Enrico Gandini Feb 10 '21 at 15:27

1 Answers1

2

This code works, and it is based on the example from Asynchronous widgets documentation mentioned in the answer.

import asyncio

from IPython.display import display
import ipywidgets as widgets


out = widgets.Output()

def wait_for_click(btn, n_clicked=0):
    future = asyncio.Future()
    
    def on_button_clicked(btn):
        btn.description = f"Clicked {n_clicked} times!"
        future.set_result(btn.description)
    
    btn.on_click(on_button_clicked)
    
    return future


n_changes = 5

btn = widgets.Button(description="Never Clicked")


async def f():
    for i in range(n_changes):
        out.append_stdout(f'did work {i}\n')
        btn_descr = await wait_for_click(btn, n_clicked=i + 1)
        out.append_stdout(f'\nasync function continued with button description "{btn_descr}"\n')
asyncio.ensure_future(f())

display(btn, out)

The most important part is wait_for_click, a function that is called in each iteration of the for loop, and updates the Button description from "Never Clicked" to "Clicked N times!". wait_for_click also returns the Button description as a string. wait_for_click is a modification of wait_for_change from the documentation: instead of waiting for a modification of the IntSlider, it waits for a click of the Button.

Enrico Gandini
  • 855
  • 5
  • 29