3

I'm trying to make a successive process of buttons clicks using ipywidgets buttons.

Click on button 1 is supposed to clear button 1 and display button 2 etc...

It looks like the introduction of the wait variable make my purge function unreachable, and I don't understand why.

from ipywidgets import Button
from IPython.display import display, clear_output

def purge(sender):
    print('purge')
    clear_output()
    wait=False

for i in range(5):
    print(f'Button number :{i}')
    btn = widgets.Button(description=f'Done', disabled=False,
                        button_style='success', icon='check')
    btn.on_click(purge)
    display(btn)
    wait=True
    while wait:
        pass
Xavier M.
  • 33
  • 3

2 Answers2

1

Your while wait: pass loop is an extremely tight loop that will likely spin a CPU core at 100%. This will bog down not just your program but perhaps even your entire computer.

I think what you want to do is to display the next button not in the for loop, but in the on_click callback.

from ipywidgets import Button
from IPython.display import display, clear_output

def purge(i):
    print(f'Button number :{i}')
    clear_output()
    btn = widgets.Button(description=f'Done', disabled=False,
                        button_style='success', icon='check')
    btn.on_click(purge, i + 1)
    display(btn)

purge(1)

Then you can put an if i == 5 in your function to do something else when they reach the last button.

Ronald
  • 1,009
  • 6
  • 13
  • Thanks for the answer, I think you solved part of the problem but the button is still blocked. The purge function is not reached. The code looks accurate in terms of logic, so I think the bug is linked to my use of the ipywidgets library. – Xavier M. May 31 '20 at 20:41
0

Although probably not the cleanest, here is my solution.

Buttons' and other ipywidgets' attributes are dynamically modifiable:

import ipywidgets as widgets
from IPython.display import display
from IPython.display import clear_output

# Create and display button
button = widgets.Button(description="Begin")
output = widgets.Output()
display(button, output)

# Initialize variable
i = 0

def update_button(args):
    global i  # Declare i as a global variable
    with output:
        print("Button %s clicked." % i)
       
        # Button attributes' change conditions
        if i<2:
            button.description = 'Next'
        else:
            button.description = 'Done'
            button.button_style='success'
            button.icon='check'
        
        # Do something different on each button press
        if i == 0:
            # Do stuff
            print('Doing stuff')
        elif i == 1:
            # Do other stuff
            print('Doing other stuff')
        elif i ==2:
            # Do some other stuff
            print('Doing some other stuff and finishing')
        i=i+1
        clear_output(wait=True)

button.on_click(update_button)
dontic
  • 63
  • 5