How to display ipython widgets after calling .close() one them

Viewed 226

I am working on a data visualisation dashboard using ipython widgets and I am trying to establish a continuous flow. My problem is that once I call widget.close() for some widget, calling display(widget) no longer does anything.

My plan would be start all over once the clearOutputButton is clicked. Does someone know what's causing this?


Cut down version of my code as it uses database calls:

import ipywidgets as widgets
from IPython.display import display

orgs_list = ["org_1", "org_2"]

selectOrg = widgets.Dropdown(options = orgs_list)
selectDays = widgets.IntSlider(min = 7, max = 90, value = 30, step = 1)

submitOrgButton = widgets.Button(description = 'Submit', button_style='info', tooltip = "Click here to submit")
submitUserButton = widgets.Button(description = 'Submit', button_style='info', tooltip = "Click here to submit")
submitDaysButton = widgets.Button(description = 'Submit', button_style='info', tooltip = "Click here to submit")
clearOutputButton = widgets.Button(description='New Query', button_style='info', tooltip='Make another query')



def submitOrgHandler(obj):
    print(f"Selected {selectOrg.label.upper()}")
    selectOrg.close()
    submitOrgButton.close()
    org_id = selectOrg.value
    user_emails = ["user_email_1", "user_email_2"]
    user_ids = ["user_id_1", "user_id_2"]
    user_tuples = [(email, _id) for email, _id in zip(user_emails, user_ids)]
        
    global selectUser
    selectUser = widgets.Dropdown(options = user_tuples)
    
    print("Please select a user:")
    display(selectUser)
    display(submitUserButton)

def submitUserHandler(obj):
    print(f"Selected {selectUser.label}")
    selectUser.close()
    submitUserButton.close()
    print("Please select a timespan:")
    display(selectDays)
    display(submitDaysButton)

def submitMetricHandler(obj):
    print(f"Selected timespan: {selectDays.value} days \n")
    n_days = selectDays.value
    selectDays.close()
    submitDaysButton.close()
    print(f'Displaying information in the last {selectDays.value} days for {selectUser.label}...')
    user_email = selectUser.label
    
    # Do some plotting here
    print("{Plot goes here!}")

    display(clearOutputButton)
    
def clearOutputHandler(obj):
    clear_output()

    print("Please select an organisation, a user and a timespan:")
    display(selectOrg)
    display(submitOrgButton)

print("Please select an organisation, a user and a timespan:")
display(selectOrg)
display(submitOrgButton)

submitOrgButton.on_click(submitOrgHandler)
submitUserButton.on_click(submitUserHandler)
submitDaysButton.on_click(submitMetricHandler)
clearOutputButton.on_click(clearOutputHandler)
1 Answers

If I understand what you want to do correctly, one thing you could do is call the clear_output() function at the beginning of each event handler function instead of closing the widgets using widget.close(). Doing that enables you to open and close the widgets as often as you want.

The code looks like that:

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

orgs_list = ["org_1", "org_2"]

selectOrg = widgets.Dropdown(options = orgs_list)
selectDays = widgets.IntSlider(min = 7, max = 90, value = 30, step = 1)

submitOrgButton = widgets.Button(description = 'Submit', button_style='info', tooltip = "Click here to submit")
submitUserButton = widgets.Button(description = 'Submit', button_style='info', tooltip = "Click here to submit")
submitDaysButton = widgets.Button(description = 'Submit', button_style='info', tooltip = "Click here to submit")
clearOutputButton = widgets.Button(description='New Query', button_style='info', tooltip='Make another query')



def submitOrgHandler(obj):
    clear_output()
    print(f"Selected {selectOrg.label.upper()}")
    org_id = selectOrg.value
    user_emails = ["user_email_1", "user_email_2"]
    user_ids = ["user_id_1", "user_id_2"]
    user_tuples = [(email, _id) for email, _id in zip(user_emails, user_ids)]
        
    global selectUser
    selectUser = widgets.Dropdown(options = user_tuples)
    
    print("Please select a user:")
    display(selectUser)
    display(submitUserButton)

def submitUserHandler(obj):
    clear_output()
    print(f"Selected {selectUser.label}")
    print("Please select a timespan:")
    display(selectDays)
    display(submitDaysButton)

def submitMetricHandler(obj):
    clear_output()
    print(f"Selected timespan: {selectDays.value} days \n")
    n_days = selectDays.value
    print(f'Displaying information in the last {selectDays.value} days for {selectUser.label}...')
    user_email = selectUser.label
    
    # Do some plotting here
    print("{Plot goes here!}")

    display(clearOutputButton)
    
def clearOutputHandler(obj):
    clear_output()

    print("Please select an organisation, a user and a timespan:")

    display(selectOrg)
    display(submitOrgButton)

print("Please select an organisation, a user and a timespan:")
display(selectOrg)
display(submitOrgButton)

submitOrgButton.on_click(submitOrgHandler)
submitUserButton.on_click(submitUserHandler)
submitDaysButton.on_click(submitMetricHandler)
clearOutputButton.on_click(clearOutputHandler)
Related