【问题标题】:How can I assign callbacks to buttons that aren't guaranteed to exist in Ploty-Dash?如何将回调分配给 Plotly-Dash 中不保证存在的按钮?
【发布时间】:2022-11-15 13:38:50
【问题描述】:

我有一个破折号程序,它根据下拉列表中的用户输入创建一到三个按钮。然后用户可以单击该按钮,程序将告诉他们最后一次按下哪个按钮。像这样:

但是,每当我选择一个不创建所有 3 个按钮的下拉值时,就会出现问题。我可以选择 1 或 2,并创建 1 或 2 个按钮,但尝试单击 button-1 或 button-2 会返回错误并且无法正确运行回调。

我收到的错误是:A nonexistent object was used in an `Input` of a Dash callback. The id of this object is `button-2` and the property is `n_clicks`. The string ids in the current layout are: [page-content, dropdown, button-row, last-selected, button-0, button-1]

我知道发生这种情况是因为我的回调将所有三个按钮都作为输入,尽管在运行回调时所有三个按钮可能都不存在,但我不确定如何解决此问题。

这是代码:


import dash
from dash.dependencies import Input, Output
import dash_bootstrap_components as dbc
from dash import Dash, dcc, html, Input, Output, callback

app = dash.Dash(__name__, external_stylesheets=[dbc.themes.ZEPHYR], suppress_callback_exceptions=True)
server = app.server 

# Layout for the form
layout = dbc.Container(
    [
        dbc.Row( children =
        [
            html.Strong('How many buttons do you want?', style={'font-size': '20px', 'width': 'auto'}),
            dcc.Dropdown([1, 2, 3],  id='dropdown'),
        ], justify='center', align='center', style={'margin-top': '20px'}
        )
    ]
)
buttons = html.Div(
    [
        dbc.Col(
            [
                dbc.Row([], id='button-row'),
                html.Div([],id='last-selected')
            ]
        )
    ]
)
app.layout = html.Div(
    [
        html.Div(children = [layout, buttons], id='page-content'),
    ]
)



@callback(Output('button-row', 'children'),
                        Input('dropdown', 'value'))
def update_button_row(dropdown):
    children = []
    for each in range(dropdown):
        children.append(dbc.Button('Button {}'.format(each), id='button-{}'.format(each)))
    return children

@callback(Output('last-selected', 'children'),
                        Input('button-0', 'n_clicks'),
                        Input('button-1', 'n_clicks'),
                        Input('button-2', 'n_clicks'),      
                        prevent_initial_call = True)
def update_last_selected(button0, button1, button2):
    ctx = dash.callback_context
    if not ctx.triggered:
        return ''
    else:
        button_id = ctx.triggered[0]['prop_id'].split('.')[0]
        return 'Last selected: {}'.format(button_id)

# Launch the app with debug mode on
if __name__ == '__main__':
    app.run_server(debug=True)

我想要一个解决方案,它允许由 update-button-row 函数创建的所有按钮在单击它们时能够在“最后选择的”div 中打印它们的名称。

感谢您的阅读!

【问题讨论】:

    标签: python plotly-dash


    【解决方案1】:

    您可以使用模式匹配回调并修改您的回调以适应first example from the docs:

    from dash import ALL
    
    @callback(Output('button-row', 'children'),
              Input('dropdown', 'value'))
    def update_button_row(dropdown):
        children = []
        for each in range(dropdown):
            button_id = {
                "type": "button",
                "index": "button-{}".format(each)
            }
            children.append(dbc.Button('Button {}'.format(each), id=button_id))
        return children
    
    @callback(Output('last-selected', 'children'),
              Input({"type": "button", "index": ALL}, "n_clicks"),      
              prevent_initial_call = True)
    def update_last_selected(n_clicks):
        ctx = dash.callback_context
        if not ctx.triggered:
            return ''
        else:
            button_id = ctx.triggered[0]['prop_id'].split('.')[0]  # This will return a stringified dictionary of the above defined button id
        return 'Last selected: {}'.format(button_id)
    

    请注意,第一个回调中的 id 属性已更改为字典。这个字典现在将由第二个回调返回(并且可以很容易地用json.loads(button_id) 解析以获得所需的输出)。

    【讨论】:

      猜你喜欢
      • 2021-05-22
      • 1970-01-01
      • 2020-03-07
      • 2021-02-25
      • 1970-01-01
      • 2020-03-17
      • 2021-05-01
      • 2021-08-02
      • 2021-06-07
      相关资源
      最近更新 更多