【问题标题】:ipywidgets: Update one widget based on results from anotheripywidgets:根据另一个小部件的结果更新一个小部件
【发布时间】:2016-05-10 16:31:56
【问题描述】:

我在 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)

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

search_selection.options = titles

产生以下错误(一个或两个,因情况而异):

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

在小部件根据来自其他小部件的搜索结果更新的意义上它仍然有效,但它给出了错误。

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

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

【问题讨论】:

    标签: python widget ipython ipywidgets


    【解决方案1】:

    您可以在分配期间向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 的解释

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

    【讨论】:

      【解决方案2】:

      我在一小时前遇到了这个确切的问题。我使用此处的最小示例编写了一个解决方案: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

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

      希望这会有所帮助。

      【讨论】:

        【解决方案3】:

        我遇到了类似的问题,解决了Registering callbacks to trait changes in the kernel

        caption = widgets.Label(value='The values of range1 and range2 are synchronized')
        slider = widgets.IntSlider(min=-5, max=5, value=1, description='Slider')
        
        def handle_slider_change(change):
            caption.value = 'The slider value is ' + (
                'negative' if change.new < 0 else 'nonnegative'
            )
        
        slider.observe(handle_slider_change, names='value')
        
        display(caption, slider)
        

        我猜这个解决方案在 2016 年不可用,或者我的问题不像想象的那么相似。

        【讨论】:

          【解决方案4】:

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

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

          Dan 的方法是最好的。以上只是说明了问题的原因。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2021-06-09
            • 1970-01-01
            • 2019-12-17
            • 2022-01-16
            • 2021-07-20
            • 1970-01-01
            • 2020-02-22
            • 2019-11-13
            相关资源
            最近更新 更多