【问题标题】:Python Dash Callback LoopingPython Dash 回调循环
【发布时间】:2021-05-06 03:24:11
【问题描述】:

我尝试学习 Python Dash 来可视化一些数据。我使用多个按钮处理 Plotly 示例:

import dash
from dash.dependencies import Input, Output
import dash_html_components as html

external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']

app = dash.Dash(__name__, external_stylesheets=external_stylesheets)

app.layout = html.Div([
    html.Button('Button 1', id='btn-nclicks-1', n_clicks=0),
    html.Button('Button 2', id='btn-nclicks-2', n_clicks=0),
    html.Button('Button 3', id='btn-nclicks-3', n_clicks=0),
    html.Div(id='container-button-timestamp')
   ])

@app.callback(Output('container-button-timestamp', 'children'),
          Input('btn-nclicks-1', 'n_clicks'),
          Input('btn-nclicks-2', 'n_clicks'),
          Input('btn-nclicks-3', 'n_clicks'))
def displayClick(btn1, btn2, btn3):
    changed_id = [p['prop_id'] for p in dash.callback_context.triggered][0]
    if 'btn-nclicks-1' in changed_id:
        msg = 'Button 1 was most recently clicked'
    elif 'btn-nclicks-2' in changed_id:
        msg = 'Button 2 was most recently clicked'
    elif 'btn-nclicks-3' in changed_id:
        msg = 'Button 3 was most recently clicked'
    else:
        msg = 'None of the buttons have been clicked yet'
    return html.Div(msg)

if __name__ == '__main__':
    app.run_server(debug=True)

代码显示最近单击了哪个按钮。我想问是否可以把它放在一个循环中,这样我就可以循环 i 个按钮,因为如果我想使用 50 个左右的按钮,这几乎是可行的。

代替

html.Button('Button 1', id='btn-nclicks-1', n_clicks=0),
html.Button('Button 2', id='btn-nclicks-2', n_clicks=0),
html.Button('Button 3', id='btn-nclicks-3', n_clicks=0),

类似:

for i in range(number_buttons):
    html.Button('Button i', id='btn-nclicks-i', n_clicks=0)

@app.callback(
    Input('btn-nclicks-i', 'n_clicks')
)

我希望能提供一些指向带有 Dash 回调的教程或示例的链接。

【问题讨论】:

标签: python loops dynamic callback plotly-dash


【解决方案1】:

最棘手的部分是将循环中创建的所有按钮作为Input 添加到callback,但您可以使用模式匹配回调来做到这一点(请参阅dash docs)。这是一个小示例,使用您提供的代码作为基础,但通过循环使用 10 个按钮:

from dash.dependencies import Input, Output, ALL
import dash_html_components as html

app = dash.Dash(__name__)

btnlst = [html.Button(
              'Button {}'.format(i),
               id={
                   'type' : 'mybuttons',
                   'index' : i,
               }
         )
         for i in range(10)]

app.layout = html.Div(btnlst + [
    html.Div(id='btn-out-container'),
])

@app.callback(Output('btn-out-container', 'children'),
                Input({'type':'mybuttons', 'index':ALL}, 'n_clicks'))
def display_click(nclicks):
    changed_id = [p['prop_id'] for p in dash.callback_context.triggered][0]
    if changed_id == '.':
        msg = 'None of the buttons have been clicked yet'
    else:
        # do additional parsing of changed_id here as necessary
        msg = 'Changed property: {}'.format(changed_id)
    return html.Div(msg)

if __name__ == '__main__':
    app.run_server(debug=True)

需要注意的重要事项:

  • 我事先创建了按钮列表btnlst,并将其添加到另一个html.Div 组件的第一个参数中。该技术是通用的,不仅适用于模式匹配回调。
  • 注意每个按钮的id 属性的形式,这是在模式匹配回调中使用它们所必需的。 idtype 可以是任何字符串,但如果您要像这样使用多个组,建议不要混用它们的名称。
  • display_clicks 中使用的changed_id 具有非常自定义的格式,正如您在查看输出时所看到的那样。您可能需要对其进行一些额外的解析,尤其是当您除了按钮列表之外还有其他 Input 时。

【讨论】:

    猜你喜欢
    • 2019-05-23
    • 2023-02-20
    • 2020-06-08
    • 2020-09-22
    • 2020-03-07
    • 1970-01-01
    • 2020-03-11
    • 2019-02-10
    • 1970-01-01
    相关资源
    最近更新 更多