ipywidgets:根据另一个部件的结果更新一个部件

hme*_*erg 6 python widget ipython ipywidgets

我在IPython中使用小部件,该部件允许用户重复搜索短语并在另一个小部件(选择小部件)中查看结果(不同的标题),然后选择其中一个结果。

简而言之:

search_text = widgets.Text(description = 'Search') 
search_result = widgets.Select(description = 'Select table')

def search_action(sender):
    phrase = search_text.value
    df = search(phrase) # A function that returns the results in a pandas df
    titles = df['title'].tolist()
    search_result.options = titles

search_text.on_submit(search_action)
Run Code Online (Sandbox Code Playgroud)

这曾经可以正常工作,但是在更新到最新版本的ipywidgets(4.0.1的5.1.3)之后,

search_selection.options = titles
Run Code Online (Sandbox Code Playgroud)

产生以下错误(一个或两个,不同):

TraitError: Invalid selection
TypeError: 'list' object is not callable
Run Code Online (Sandbox Code Playgroud)

它仍然可以在某种意义上起作用,即该小部件会根据来自其他小部件的搜索结果来更新结果,但是会出现错误。

根据另一个窗口小部件的结果在一个窗口小部件中设置选项的正确方法是什么?

(编辑:添加了更详细的错误消息)

小智 5

我在一小时前遇到了这个确切的问题。我在这里使用了最小的示例,找到了一个解决方案:动态更改IPython笔记本小部件和Spyre中的下拉列表,因为我自己的要求是具有动态链接列表。我相信您可以使用该解决方案来适应您的要求。

关键是预先生成所有下拉列表/选择。由于某种原因,w.options = l只能设置,w._options_labels而不能w.options。随后对选定值of的验证w将严重失败。

import ipywidgets as widgets
from IPython.display import display

geo={'USA':['CHI','NYC'],'Russia':['MOW','LED']}
geoWs = {key: widgets.Select(options=geo[key]) for key in geo}

def get_current_state():
    return {'country': i.children[0].value,
            'city': i.children[1].value}

def print_city(**func_kwargs):
    print('func_kwargs', func_kwargs)
    print('i.kwargs', i.kwargs)
    print('get_current_state', get_current_state())

def select_country(country):
    new_i = widgets.interactive(print_city, country=countryW, city=geoWs[country['new']])
    i.children = new_i.children

countryW = widgets.Select(options=list(geo.keys()))
init = countryW.value
cityW = geoWs[init]

countryW.observe(select_country, 'value')

i = widgets.interactive(print_city, country=countryW, city=cityW)

display(i)
Run Code Online (Sandbox Code Playgroud)

最后请注意,获取小部件的最新状态并非易事。这些是

  • 通过直接从孩子的价值观中获取get_current_state。这是可以信任的。
  • 从交互式实例,通过 i.kwargs
  • 从提供的参数到 print_city

后两者有时可能会过时,由于各种原因,我不想进一步了解。

希望这可以帮助。


Dan*_*ien 5

您可以在分配给的过程中保留有关的通知options

with search_result.hold_trait_notifications():
    search_result.options = titles
Run Code Online (Sandbox Code Playgroud)

从而:

search_text = widgets.Text(description = 'Search') 
search_result = widgets.Select(description = 'Select table')

def search_action(sender):
    phrase = search_text.value
    df = search(phrase) # A function that returns the results in a pandas df
    titles = df['title'].tolist()
    with search_result.hold_trait_notifications():
        search_result.options = titles
Run Code Online (Sandbox Code Playgroud)

请参阅下面的hmelberg解释

“错误的根源是小部件还具有value属性,并且该值可能不在新的选项列表中。因此,小部件值可能在短时间内被“孤立”,并产生错误。”