In my code, I can select items in country, but, after selected, I cannot select items in city.
Only after I type somethings in city and erase them, I can select items in city.
Can somebody kindly give me some hint to figure out the problems?
Both of your examples have this line that I find strange:
cityW.observe(update_cityW_options)
This should actually be
countryW.observe(update_cityW_options)
So that when a new country is selected you show its cities in the city widget.
With Combobox I would also add cityW.value = "" into the try block to clear the input box because leaving a city from another country doesn’t make much sense after country change.
With these changes things work pretty much as expected for me =).
Continuing this topic, I have another problem if I want to use multiple .observe function
from ipywidgets import Combobox, interact
geo0 = {'USA':['CHI','NYC'],'Russia':['MOW','LED']}
geo1 = {"Taiwan":['TPE', "HSI"], "China":["SHA","SHE"]}
countryW, cityW = [], []
# Define list of comboboxes
for idx in range(0, 2):
var = eval("geo" + str(idx))
countryW.append(Combobox(options=list(var.keys()), description="Country "+str(idx)))
cityW.append(Combobox(description="City "+str(idx)))
# Define the handler
def update_options(*arg):
global idx
var = eval("geo" + str(idx))
try:
cityW[idx].options = [""]
cityW[idx].options = var[countryW[idx].value]
except:
cityW[idx].options = [""]
# Ask for the callback
for idx in range(0, 2):
countryW[idx].observe(update_options)
# Print the country name & city name
for idx in range(0, 2):
@interact(country = countryW[idx], city = cityW[idx])
def print_city(country, city):
print(country, city)
I don’t know why only the final callback works in this code, that is, there is no option in the City 0 column
You use the idx variable that’s going to be equal to 1 after your code runs. So the callback will always run with idx == 1.
The observe handler actually gets a change dict when it runs. You can use change['owner'] to get the widget instance and find its index in the countryW list.
# Define the handler
def update_options(change):
idx = countryW.index(change['owner'])
# update city options...
# Ask for the callback
for idx in range(0, 2):
countryW[idx].observe(update_options, names='value')
Here I’ve also added names='value' to the observe call so that your function only runs when widget value changes.