【问题标题】:Dynamically generate tickboxes combined with a search in using jupyter widgets使用 jupyter 小部件动态生成与搜索相结合的复选框
【发布时间】:2019-10-04 12:57:48
【问题描述】:

我已经构建了一个 jupyter notebook 来分析和对比历史数据。因为数据库非常大,我使用了搜索+观察小部件来允许用户选择他们想要的实验,而不是滚动浏览所有数据。现在所有实验的所有复选框都已生成,但这既太大而无法放入盒子中,并且占用了大量时间。

有没有办法默认只显示最后 10 个实验,并且只在搜索后生成所需的复选框?

我基于此gist 编写代码。我已经尝试将复选框小部件移动到 else 循环中,但这不起作用。此外,我的代码中的全局/局部变量情况似乎很混乱。

import ipywidgets as widgets

#Generate a dummy list
Allfileslist = ["Experiment {}".format(x) for x in range(600)]
#Search box + generate ALL the checkboxes, this seems to be the bottleneck
search_widget = widgets.Text(placeholder='Type for older experiments',                 description= 'Search:')
experiments = {eachfilename: widgets.Checkbox(description=eachfilename, value=False) for eachfilename in Allfileslist}
options = [experiments[eachfilename] for eachfilename in Allfileslist]
options_widget = widgets.VBox(options, layout={'overflow': 'auto'})


def whentextischanged (change):
    """Dynamically update the widget experiments"""
    search_input = change['new']
    if search_input == '':
        # Reset search field, default to last 9 experiments
        new_options = [experiments[eachfilename] for eachfilename in Allfileslist[-10:]]
    else:
        # Filter by search
        close_matches = [x for x in Allfileslist if search_input.upper() in x]
        ### magic code that generates only the match boxes ###
        new_options = [experiments[eachfilename] for eachfilename in close_matches]

    options_widget.children = new_options

#Generate the vbox, search
multi_select = widgets.VBox([search_widget, options_widget])
search_widget.observe(whentextischanged, names='value')
#serve it up
multi_select

有没有办法只生成加快速度所需的复选框?

更新 我将 ac24 的答案与一些修改结合起来,它几乎可以满足它的需要。唯一没有的是在搜索框一开始为空时显示默认值。之后,清除搜索框会显示正确的行为。

import ipywidgets as widgets

#Generate a dummy list
Allfileslist = ["{}".format(x) for x in range(600)]
#Search box + generate some checboxes
search_widget = widgets.Text(placeholder='Type for older experiments', description= 'Search:',value='')
experiments = {}
options_widget = widgets.VBox(layout={'overflow': 'auto'})
default_options = [widgets.Checkbox(description=eachfilename, value=False) for eachfilename in Allfileslist[-10:]]

def whentextischanged (change):
    """Dynamically update the widget experiments"""
    search_input = change['new']
    if search_input == '':
        # Reset search field, default to last 9 experiments
        new_options = default_options
    else:
        # Filter by search
        close_matches = [x for x in Allfileslist if search_input.lower() in x.lower()][:10]
        for name in close_matches:
            if name not in experiments:
                experiments[name] = widgets.Checkbox(description=name, value=False)
        new_options = [experiments[eachfilename] for eachfilename in close_matches]

    options_widget.children = new_options

#Generate the vbox, search
multi_select = widgets.VBox([search_widget, options_widget])
search_widget.observe(whentextischanged, names='value')
multi_select

【问题讨论】:

    标签: jupyter-notebook ipywidgets


    【解决方案1】:

    尝试先创建一个空字典,然后在您接近所需的实验选择时使用复选框填充。

    import ipywidgets as widgets
    
    #Generate a dummy list
    Allfileslist = ["{}".format(x) for x in range(600)]
    #Search box + generate ALL the checkboxes, this seems to be the bottleneck
    search_widget = widgets.Text(placeholder='Type for older experiments',                 description= 'Search:')
    # experiments = {eachfilename: widgets.Checkbox(description=eachfilename, value=False) for eachfilename in Allfileslist}
    experiments = {}
    options_widget = widgets.VBox(layout={'overflow': 'auto'})
    
    
    def whentextischanged (change):
        """Dynamically update the widget experiments"""
        search_input = change['new']
        if search_input == '':
            # Reset search field, default to last 9 experiments
            new_options = [experiments[eachfilename] for eachfilename in Allfileslist[-10:]]
        else:
            # Filter by search
            close_matches = [x for x in Allfileslist if search_input.lower() in x.lower()][:10]
            for name in close_matches:
                if name not in experiments:
                    experiments[name] = widgets.Checkbox(description=name, value=False)
    
            ### magic code that generates only the match boxes ###
            new_options = [experiments[eachfilename] for eachfilename in close_matches]
    
        options_widget.children = new_options
    
    #Generate the vbox, search
    multi_select = widgets.VBox([search_widget, options_widget])
    search_widget.observe(whentextischanged, names='value')
    #serve it up
    multi_select
    
    

    然后,一旦您选择了几个选项,请致电 [key for key, exp_check in exp_checkboxes.items() if exp_check.value] 以查看选择的值。

    【讨论】:

    • 感谢您的回答!我稍微修改了你的答案,它几乎可以工作。只是没有显示默认选择,有什么想法吗?
    • Hacky 除了将whentextischanged({'new':''}) 放在display(multi_select) 之前的倒数第二行吗?
    • 非常 hacky 但不幸的是完全符合我通常的编码标准。非常感谢!
    猜你喜欢
    • 2023-03-08
    • 1970-01-01
    • 2011-07-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-10
    相关资源
    最近更新 更多