动态更改IPython笔记本小部件和Spyre中的下拉菜单

时间:2015-02-15 17:53:49

标签: python ipython ipython-notebook

我在IPython笔记本(作为HTML小部件的一部分)和Spyre应用程序(作为dropdown元素)中有一个下拉列表,比如选择一个大陆并且我想添加第二个下拉列表选择非洲大陆的国家。现在很明显,第二个下拉列表中的选项取决于第一个下拉列表的值。我很难找到一种方便的方法来获得一个可以更新这个UI元素的回调函数。

我在IPython笔记本中差不多完成了这个,我有一个interact函数,在被调用的函数中,我用第二个下拉列表创建了第二个interact元素。但每当我更改第一个下拉列表时,都会创建一个新的下拉元素,因此每次更改时我都会得到一个额外的下拉列表。但我只希望更新一个下拉列表,就是这样。

希望问题清楚。谢谢。

4 个答案:

答案 0 :(得分:18)

使用interactive代替interact并更新您的小部件:

from IPython.html import widgets
from IPython.display import display

geo={'USA':['CHI','NYC'],'Russia':['MOW','LED']}

def print_city(city):
    print city

def select_city(country):
    cityW.options = geo[country]


scW = widgets.Select(options=geo.keys())
init = scW.value
cityW = widgets.Select(options=geo[init])
j = widgets.interactive(print_city, city=cityW)
i = widgets.interactive(select_city, country=scW)
display(i)
display(j)

答案 1 :(得分:3)

import datetime
import ipywidgets as ipyw

from bokeh.models.widgets.inputs import AutocompleteInput
from IPython.display import display

dp1 = ipyw.Dropdown(options = ['Asia','Europe','Africa'])
dp2 = ipyw.Dropdown(options = ['India','China','Pakistan','Tibet'])
asia_list = ['India','China','Pakistan','Tibet']
europe_list = ['Germany','France','Italy']
africa_list = ['south africa','Nigeria','Kenya']
global_vbox = ipyw.VBox()
global_vbox.children = [dp1,dp2]
display(global_vbox)
def continent_change_event(x):
    global dp1
    global dp2
    list_name = dp1.value
    dp2.index = None #This line is very important for setting the values for widgets other than widget with observe method
    dp2.index = 0
    if(list_name == 'Asia'):
        dp2.options = asia_list
    elif(list_name == 'Europe'):
        dp2.options = europe_list
    else:
        dp2.options = africa_list

dp1.observe(continent_change_event)

答案 2 :(得分:2)

对于使用widgets.interactive的用户:在主要功能中更新动态窗口小部件的选项:

import ipywidgets as widgets 
geo={'USA':['CHI','NYC'],'Russia':['MOW','LED']}

def main_function(city, country):
    print (f'{city} is a city in {country}')
    cityW.options = geo[country]    

scW = widgets.Select(options=geo.keys())
cityW = widgets.Select(options=geo[init])

widgets.interactive(main_function, city=cityW, country=scW)

注意:这仅与最受好评的答案不同,只有一个交互功能,而不是两个。奖励:如果要将修订参数传递给主函数,请使用name=widgets.fixed("Bob")see here)。

答案 3 :(得分:0)

投票最多的答案是有用的,但对我来说似乎有点笨拙。经过一段时间的搜索,我发现基于here的答案Jupyter docs对我来说更受欢迎。我对其进行了调整,并提供以下内容。

from ipywidgets import interact, Dropdown

geo = {'USA':['CHI','NYC'],'Russia':['MOW','LED']}
countryW = Dropdown(options = geo.keys())
cityW = Dropdown()

def update_cityW_options(*args): # *args represent zero (case here) or more arguments.
    cityW.options = geo[countryW.value]
cityW.observe(update_cityW_options) # Here is the trick, i.e. update cityW.options based on countryW.value.

@interact(country = countryW, city = cityW)
def print_city(country, city):
    print(country, city)

作为替代方案,我还发现我可以在cityW.options函数中更新print_city,这是更清楚的做法!

from ipywidgets import interact, Dropdown

geo = {'USA':['CHI','NYC'],'Russia':['MOW','LED']}
countryW = Dropdown(options = geo.keys())
cityW = Dropdown()

@interact(country = countryW, city = cityW)
def print_city(country, city):
    cityW.options = geo[country] # Here is the trick, i.e. update cityW.options based on country, namely countryW.value.
    print(country, city)