根据 python dash 中的按钮更改回调的输出?

问题描述 投票:0回答:1

我正在使用 Python dash,并且有一个回调每 1000 毫秒更新一次并输出一个虚拟值(比如回调运行的次数)。

我想在按下按钮时更改回调的输出值。

我找到了2个选择:

  1. 使用2个回调
  2. 使用隐藏的div
# Using 2 callbacks
from dash import dash, dcc, html, Input, Output, State
app = dash.Dash(__name__)

app.layout = html.Div(
    [
        dcc.Interval(id="interval", interval=1000),  
        html.Button("Press", id="button"), 
        html.Div(id="output")  
    ]
)
@app.callback(
    Output("output", "children"),
    [Input("interval", "n_intervals")],
    [State("button", "n_clicks")]
)
def update_output(n_intervals, n_clicks):
    if n_clicks == 0:
        return f"Interval: {n_intervals} - Button not pressed"
    if n_clicks != 0:
        return f"Interval: {n_intervals} - Button pressed"

@app.callback(
    Output("button", "n_clicks"),
    [Input("output", "children")]
)
def reset_button(n):
    return 0

if __name__ == "__main__":
    app.run_server(debug=True)
# Using a hidden div
from dash import dash, dcc, html, Input, Output, State, callback_context

app = dash.Dash(__name__)

app.layout = html.Div(
    [
        dcc.Interval(id="interval", interval=1000),  
        html.Button("Press", id="button"),  
        html.Div(id="output"),  
        html.Div(id="hidden-div", style={"display": "none"}, children="0")  
    ]
)

@app.callback(
    [Output("output", "children"), Output("hidden-div", "children")],
    [Input("interval", "n_intervals"), Input("button", "n_clicks")],
    [State("hidden-div", "children")] 
)
def update_output(n_intervals, n_clicks, hidden_clicks):
    ctx = callback_context
    if ctx.triggered[0]["prop_id"] == "button.n_clicks":
        return f"Interval: {n_intervals} - Button pressed", hidden_clicks
    else:
        return f"Interval: {n_intervals} - Button not pressed", hidden_clicks

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

最好的解决方案是什么?

python plotly-dash
1个回答
0
投票

如果我必须选择,我会说第一个,因为它比第二个更容易阅读。 但第二个想法并没有那么糟糕。事实上,我想提出一个替代方案。 ctx 有一个属性(称为trigger_id),它是触发回调的人的值(字符串)(官方文档)。所以我将代码重写如下:

@app.callback(
    Output("output", "children"),
    [Input("interval", "n_intervals"), 
     Input("button", "n_clicks")]
)
def update_output(n_intervals, n_clicks):
    if ctx.triggered_id == 'interval':
        return f"Interval: {n_intervals} - Button not pressed"
    return f"Interval: {n_intervals} - Button pressed"

正如您所看到的,您减少了函数数量并提高了性能,因为在第一个代码中您使用了 2 个“if”语句,而在第二个代码中您访问了一个列表(使用触发的_id 您只进行了访问到字符串)。

但是,Dash 建议您创建清晰的函数,不要在单个函数中创建太多的输入和输出。但有时也有特殊情况,就像这里(我认为)。

© www.soinside.com 2019 - 2024. All rights reserved.