【问题标题】:How to prevent infinite loop with two widgets that update each other?如何防止两个相互更新的小部件的无限循环?
【发布时间】:2021-03-29 16:13:14
【问题描述】:

我正在尝试使用Jupyter Widgets,看看是否可以制作更好的this 版本,但显然即使更改不是来自用户,观察处理程序也会触发,因此它会创建一个小部件的无限循环改变另一个。最小的例子:

import ipywidgets as widgets

a = widgets.FloatText(description='a:')
b = widgets.FloatText(description='b:')


def on_a_change(change):
    b.value = change['new'] + 1
    
a.observe(on_a_change, names='value')


def on_b_change(change):
    a.value = change['new'] + 1

b.observe(on_b_change, names='value')


display(a)
display(b)

有没有办法只触发用户发起的更改?换句话说,用户更新了一个文本框,然后其他文本框也随之更新,但这些更新不会触发更多更新。

【问题讨论】:

标签: python jupyter infinite-loop onchange ipywidgets


【解决方案1】:

您也可以在更改值时unobserve一个函数,然后再将其重置。

def on_a_change(change):
    b.unobserve(on_b_change, names='value')
    b.value = change['new'] + 1
    b.observe(on_b_change, names='value')

【讨论】:

    【解决方案2】:

    不确定我是否理解要求,但如果是“多更新一个”,那么您可以尝试以下操作

    import ipywidgets as widgets
    
    a = widgets.FloatText(description='a:')
    b = widgets.FloatText(description='b:')
    
    def update_one(x):
        return x + 1
    
    widgets.link((a, 'value'), (b, 'value'), (update_one, update_one))
    
    display(a)
    display(b)
    

    widgets.link 似乎可以解决问题,如果您使用widgets.link.__doc__,您可以查看文档并且它接受第三个参数。

    >>> print(widgets.link.__doc__)
    Link traits from different objects together so they remain in sync.
    
        Parameters
        ----------
        source : (object / attribute name) pair
        target : (object / attribute name) pair
        transform: iterable with two callables (optional)
            Data transformation between source and target and target and source.
    

    所以我添加了一个可迭代的可调用对象,并使其返回 1 超过您输入的值。

    【讨论】:

    • link 看起来会起作用!我以为这只是为了让事物相互跟踪,但转换的能力使它非常适合我正在做的事情
    • 工作(虽然加载速度当然比 javascript 慢得多):mybinder.org/v2/gh/endolith/unit_converter/…
    • 看起来很酷,感谢您向我介绍 binder :D
    • 那是 Voilà 渲染图,普通的 Binder 笔记本在这里:mybinder.org/v2/gh/endolith/unit_converter/HEAD
    • 我想知道您是如何设法链接多个小部件的,这是一些不错的字典操作,我正打算询问但您链接了源代码:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-22
    • 1970-01-01
    • 2021-05-26
    相关资源
    最近更新 更多