提问人:disguisedtoast 提问时间:10/20/2023 更新时间:10/21/2023 访问量:69
在回调执行期间禁用 Plotly Dash 组件,然后在回调完成后重新启用它
Disable a Plotly Dash component during callback execution, then re-enabling it after the callback has finished
问:
我有 Plotly Dash 组件,需要在触发回调后禁用。回调运行完毕后,需要启用相同的组件。我尝试了以下方法。虽然组件被禁用,但在完成回调函数后不会启用。
from dash.exceptions import PreventUpdate
from dash_extensions.enrich import (
Output,
DashProxy,
html,
Input,
MultiplexerTransform,
)
from time import sleep
app = DashProxy(__name__, transforms=[MultiplexerTransform()])
app.layout = html.Div(
[
html.Button(id="button", children="input-button", style={"color": "#FF0000"}),
html.Div(id="trigger", children=None, style={"display": "none"})
],
)
@app.callback(
[
Output("button", "disabled"),
Output("button", "style"),
Output("trigger", "children"),
],
[
Input("trigger", "children")
],
prevent_initial_call=True
)
def enable_components_after_export(trigger):
if trigger == 1:
return [
False, {"color": "#FF0000"}, 0
]
raise PreventUpdate
@app.callback(
[
Output("button", "disabled"),
Output("button", "style")
],
[
Input("button", "n_clicks"),
],
prevent_initial_call=True
)
def disable_components_on_export_button_click(button):
if (button is not None and button > 0):
return [
True, {"color": "#808080"}
]
raise PreventUpdate
@app.callback(
[
Output("trigger", "children")
],
[
Input("button", "n_clicks"),
],
prevent_initial_call=True
)
def callback_function(button):
if button is not None and button > 0:
sleep(5)
return [1]
raise PreventUpdate
if __name__ == "__main__":
app.run(debug=False)
在回调期间禁用组件,然后在完成回调后重新启用组件的正确方法是什么?另外,我记得 Dash 不支持多个回调输出,这就是使用 DashProxy 和 MultiplexerTransform 的原因,尽管我不确定这是否导致了我的问题。
包版本
dash 2.12.1 pypi_0 pypi
dash-bootstrap-components 1.5.0 pypi_0 pypi
dash-core-components 2.0.0 pypi_0 pypi
dash-extensions 0.1.11 pypi_0 pypi
dash-html-components 2.0.0 pypi_0 pypi
dash-renderer 1.9.1 pypi_0 pypi
答:
0赞
EricLavault
10/21/2023
#1
我不确定使用这里是否应该解决这个问题,但无论如何,由于 2.9 版 Dash 允许重复的回调输出:多个回调可以针对相同的输出,唯一的事情就是在回调输出中指定,例如。DashProxy
allow_duplicate=True
@app.callback(
[
Output("button", "disabled", allow_duplicate=True),
Output("button", "style", allow_duplicate=True),
Output("trigger", "children", allow_duplicate=True),
],
[
Input("trigger", "children")
],
prevent_initial_call=True
)
请注意,您也可以使用简单的后台回调(即一个回调而不是三个回调)来实现此目的。
您可以通过设置回调来配置回调以在后台运行。使用您配置的后端管理器来运行回调逻辑的回调。您可以将此管理器实例作为关键字参数提供给应用构造函数,或作为装饰器的参数。
background=True
background=True
dash.Dash
background_callback_manager
manager
@dash.callback
这个想法是使用允许根据回调状态设置组件属性的参数(即在回调运行时禁用按钮):running
@app.callback(
Output("trigger", "children"),
Input("button", "n_clicks"),
background=True,
running=[
(Output("button", "disabled"), True, False),
(Output("button", "style"), {"color": "#808080"}, {"color": "#FF0000"}),
],
prevent_initial_call=True
)
def callback_function(button):
if button is not None and button > 0:
time.sleep(5)
return [1]
raise PreventUpdate
0赞
Waleed Malik
10/21/2023
#2
使用Dash v2.9+,您可以有多个回调来针对相同的输出。下面是一个完整的工作示例,说明如何在触发回调函数后禁用该按钮:
from dash import Dash, html, Input, Output, no_update
from time import sleep
app = Dash(__name__)
app.layout = html.Div(
[
html.Button(id="button", children="input-button", n_clicks=0, style={"color": "#FF0000"}),
html.Div(id="trigger", children=None)
],
)
@app.callback(
Output("button", "disabled", allow_duplicate=True),
Input("button", "n_clicks"),
prevent_initial_call=True,
)
def disable_btn(n):
if n:
return True
return no_update
@app.callback(
Output("trigger", "children"),
Output("button", "disabled"),
Input("button", "n_clicks"),
prevent_initial_call=True,
)
def update_content(n):
if n:
sleep(5)
return 1, False
return no_update
if __name__ == "__main__":
app.run_server(debug=True)
评论