【问题标题】:Using buttons with @interact使用带有 @interact 的按钮
【发布时间】:2019-09-08 01:31:28
【问题描述】:

编辑:为清楚起见,于 2019 年 9 月 8 日 1330 UTC 重写

在 Jupyter 笔记本中,我想探索由日期选择器小部件选择的日期。我已经知道这样做的方法是使用 @interact 并将 datepicker 小部件作为交互函数的参数,如下所示:

def explore_dates(d1=widgets.DatePicker(value=pd.to_datetime('2018-07-10', format='%Y-%m-%d'), description='Date')):

但我需要“下一个假期”和“上一个假期”按钮来从选定的日期移动到下一个假期。我已经将一组假期存储为 datetime.datetime 对象。

所以我尝试将按钮对象添加到 @interact 函数的参数中,如下所示:

@interact

def explore_dates(d1=widgets.DatePicker(value=pd.to_datetime('2018-07-10', format='%Y-%m-%d'), description='Date'),
                 prev_button = widgets.Button(description="Prev Holiday"),
                 next_button = widgets.Button(description="Next Holiday")):

那没用。错误说带有按钮小部件的行“无法转换为小部件”。嗯,我还以为已经是小部件了……

我的下一个想法是将按钮代码放在函数中,而不是作为参数:

def explore_dates(d1=widgets.DatePicker(value=pd.to_datetime('2018-07-10', format='%Y-%m-%d'), description='Date')):

prev_button = widgets.Button(description="Prev Holiday")
next_button = widgets.Button(description="Next Holiday")
prev_button.on_click(prev_holiday_callback)
next_button.on_click(next_holiday_callback)
box=widgets.HBox([prev_button,next_button])
display(box)

屏幕上有按钮,我可以按下它们并运行我的回调例程。但是,当将日期选择器设置为(如上)作为@interact 的参数时,似乎不再可以使用其 .value 属性重置其日期。 (参见上面的代码)尝试设置 d1.value 会导致错误。

我想我可以完全摆脱@interact,只需将日期选择器和两个按钮都放入主线代码中。 但当时我不知道如何重现@interact 的功能。没有无限循环等待来自其中一个小部件的点击或观察事件,除了@interact,我不知道如何告诉 Python/Jupyter “嘿,冷静下来,直到小部件事件导致回调唤醒代码”。

如果有帮助,这里是我的按钮回调例程。

def button_click_common():
    global button_flag
    global button_date
    global holidays
    
    for i in range(len(holidays)):
        if(holidays[i]<button_date): # haven't passed the prior holiday yet
            continue
        
        # Now holidays[i] has to either be same as or after button_date
        
        prior_holiday = i-1 # prior holiday is the one we just passed that was prior
        next_holiday = i    # assume at first we are between dates
        if holidays[i]==button_date:
            next_holiday +=1        # if we were already on a holiday date, next becomes the following one
        return prior_holiday, next_holiday

def prev_holiday_callback(_):
    global button_flag
    global button_date
    global holidays
    
    prior_holiday,_ = button_click_common()
    
    button_date = holidays[prior_holiday]
    button_flag = True
    
def next_holiday_callback(_):
    global button_flag
    global button_date
    global holidays
    
    _,next_holiday = button_click_common()
    
    button_date = holidays[next_holiday]    
    button_flag = True  

这里的想法是回调将button_date更新为下一个假期的日期,并设置标志button_flag。然后 explore_dates 函数中的代码(未显示)将测试该标志。但是当它被定义为@interact 函数的参数时,我不知道如何使用新日期更新日期选择器小部件。

感觉我做错了。欢迎任何建议或指导...

提前致谢!

【问题讨论】:

    标签: python jupyter-notebook ipywidgets


    【解决方案1】:

    我不确定我是否理解您要达到的确切目标,但交互最适合采用数字输入的函数,而不是离散输入或 Python 对象(如日期)。

    我整理了一些代码来说明如何使用前进和后退按钮来更新日期选择器,这可能不是您想要的,但也许您可以从那里描述更改?

    import ipywidgets as ipyw
    from datetime import date
    
    idx = 0
    date_picker = ipyw.DatePicker()
    date_picker.value = month_starts[idx]
    start_button = ipyw.Button(description='Prev')
    end_button = ipyw.Button(description='Next')
    
    display(date_picker, start_button, end_button)
    
    def change_date(button):
        global idx
        if button.description=='Prev':
            if idx-1<0:
                pass
            else:
                date_picker.value = month_starts[idx-1]
                idx -= 1
    
        elif button.description=='Next':
            if idx+1>=len(month_starts):
                pass
            else:
                date_picker.value = month_starts[idx+1]
                idx += 1
    
    start_button.on_click(change_date)
    end_button.on_click(change_date)
    
    

    【讨论】:

    • 谢谢。这与我已经发布的代码非常相似,所以我想我们同意基本方法。问题是交互功能如何工作。如果我将 datepicker 小部件作为交互函数的参数,则无法使用 .value 属性重置其值。如果我按照您在此处描述的方式显示日期选择器,我将获得日期选择器并可以对其进行更新,但更改它不会导致交互功能再次运行。
    • 感谢您的回答。我实际上是在尝试完成一些不同的事情,但最终我自己想通了。我将在此答案上单击“已回答”,因为它帮助我找到了自己解决问题的方法。再次感谢!
    猜你喜欢
    • 1970-01-01
    • 2016-06-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-11
    • 2018-01-20
    • 2015-05-18
    相关资源
    最近更新 更多