更新下拉小部件(ipywidget)

时间:2018-05-13 20:50:19

标签: python jupyter-notebook ipywidgets

我使用交互式ipywidget下拉列表来过滤一定数量的数据并用图表绘制图形。

我的问题在于下拉小部件的更新:这是一个简化的例子:

    import ipywidgets as widgets
from ipywidgets import *
from IPython.display import display, clear_output, HTML

def update_drop2(*args):
    if Drop1.value=='R':
        Drop2.options = {'un':'1','trois':'3','quatre':'4'}
    if Drop1.value=='B':
        Drop2.options = {'un':'1','trois':'3','quatre':'4'}
    if Drop1.value=='G':
        Drop2.options = {'deux':'2','quatre':'4','trois':'3'}

def action(*args):
    print('action')


Drop1 = widgets.Dropdown(
        options = {'red':'R','blue':'B','green':'G'},
        value = 'R',
        description='Drop1 :',
        disabled=False,
        continuous_update=False,
        style = {'description_width': 'initial'}
        )

Drop2 = widgets.Dropdown(
        options = {'un':'1','deux':'2','trois':'3'},
        value = '3',
        description='Drop2 :',
        disabled=False,
        continuous_update=False,
        style = {'description_width': 'initial'}
        )

display(Drop1,Drop2)

Drop1.observe(update_drop2,'value')
Drop2.observe(action,'value')

drop1更改了drop2的选项。 drop1的任何更改(和drop2应该启动一个动作(这里只是一个例子的打印)

  • 当drop2的选项列表不同并由drop1更改时,drop2.value会自动设置为新列表的第一个值,即使选择的值已经存在于上一个列表中。如果它在新列表中仍然可用,是否可以选择保留此值? (例如:选择drop1 = R,drop2 =' trois然后执行drop1 =' G':drop2自动设置为' 2'。选择drop1 = R,drop2 = 3然后执行drop1 =' B':drop2保留在' 3')

  • 如果我在更新drop2.options后尝试强制drop2.value,则会对drop2 = 2个动作进行2次更改...我无法找到避免它的方法..所以另外,有时我会重复动作,有时候我没有动作......

感谢您的帮助

1 个答案:

答案 0 :(得分:0)

下面的代码应该可以解决您的两个问题:

import ipywidgets as widgets
from ipywidgets import *
from IPython.display import display, clear_output, HTML

out = widgets.Output()

def action(*args):
    with out:
        print('action')
        

def update_drop2(*args):
        temp = Drop2.value
        Drop2.unobserve(action, 'value')
        
        if Drop1.value=='R':
            Drop2.options = {'un':'1','trois':'3','quatre':'4'}
        if Drop1.value=='B':
            Drop2.options = {'un':'1','trois':'3','quatre':'4'}
        if Drop1.value=='G':
            Drop2.options = {'deux':'2','quatre':'4','trois':'3'}
        
        if str(temp) in Drop2.options.values():
            Drop2.value = temp
        
        Drop2.observe(action, 'value')
        action()

Drop1 = widgets.Dropdown(
        options = {'red':'R','blue':'B','green':'G'},
        value = 'R',
        description='Drop1 :',
        disabled=False,
        continuous_update=False,
        style = {'description_width': 'initial'}
        )

Drop2 = widgets.Dropdown(
        options = {'un':'1','deux':'2','trois':'3'},
        value = '3',
        description='Drop2 :',
        disabled=False,
        continuous_update=False,
        style = {'description_width': 'initial'}
        )

display(Drop1, Drop2, out)

Drop1.observe(update_drop2,'value')
Drop2.observe(action, 'value')
  1. 我添加了 Output 小部件来实际显示输出。

  2. 要修正您的第一个要点,可以使用临时变量 temp 来检查 Drop2 的值是否包含在 Drop2.options 的字典中并相应地更改该值如果需要的话。 Drop2.value 发生了变化,因为字典是从 python 3.7 开始排序的。

  3. 要解决您的第二个要点,即在更改 Drop1.value 时不要进行两次调用,这也可能会更改 Drop2.valueDrop2.options,您可以不观察 {{ 1}} 在函数 Drop2 中,最后再次观察它。