ipywidgets:基于anoth的结果更新一个小部件

2024-09-22 20:18:40 发布

您现在位置:Python中文网/ 问答频道 /正文

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

简而言之:

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)

这以前工作得很好,但是在更新到最新版本的ipywidgets(4.0.1版本的5.1.3)之后,看起来

search_selection.options = titles

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

TraitError: Invalid selection
TypeError: 'list' object is not callable

它仍然工作在这样的意义上:小部件根据来自另一个小部件的搜索结果进行更新,但它会给出一个错误。

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

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


Tags: text版本dfsearch部件错误actiondescription
3条回答

在分配给options期间,您可以保存的通知:

with search_result.hold_trait_notifications():
    search_result.options = titles

因此:

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

参见下面的hmelberg解释

"The root of the error is that the widget also has a value property and the value may not be in the new list of options. Because of this, widget value may be "orphaned" for a short time and an error is produced."

错误的根源在于小部件也有一个值属性,该值可能不在新的选项列表中。因此,小部件值可能在短时间内“孤立”,并产生错误。

解决方案是在将小部件值分配给小部件之前将其分配给选项列表(如果需要,在之后删除值/选项),或者如Dan所写:使用create a hold_trait-notifications()

丹的方法是最好的。以上只是解释了问题的原因。

我一小时前就遇到了这个问题。我用这里的最小示例Dynamically changing dropdowns in IPython notebook widgets and Spyre拼凑出了一个解决方案,因为我自己的需求是动态链接列表。我相信你能用这个解决方案来适应你的需求。

关键是预生成所有下拉列表/选择。出于某种原因,w.options = l只设置w._options_labels,而不设置w.options。随后对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)

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

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

后两种方法有时会过时,因为种种原因,我不想进一步了解。

希望这有帮助。

相关问题 更多 >