“循环依赖”但工作完美;如何解决

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

此程序允许您在长时间处理过程中生成活动(例如进度条),并在活动结束时停止。

  1. 第一个回调会生成带有
    dcc.interval
    的活动。
  2. 第二个回调控制 Activity 的启动和停止。
  3. 第三个模拟了一个漫长的充电过程。

如何去除循环依赖? 我尝试从第二个回调中删除

Output("start", "n_clicks")
,因为它似乎导致了问题,但随后不再触发消息“停止”和“开始”。

import dash
import dash_bootstrap_components as dbc
import time

from dash import callback, callback_context, dcc, html, no_update
from dash.dependencies import Input, Output
from dash.exceptions import PreventUpdate

app = dash.Dash(__name__)

app.layout = html.Div(
    [
        dbc.Button("Start", id="start", n_clicks=0),
        dcc.Store(id="stop", storage_type="memory", data=""),
        dcc.Interval(id="interval", disabled=True, interval=500, n_intervals=0),
        html.Div(id="progress"),
    ]
)


@callback(
    Output("progress", "children"),
    Input("interval", "n_intervals"),
    prevent_initial_call=True,
)
def timer_callbak(interval):
    return interval


@callback(
    Output("start", "n_clicks"),
    Output("interval", "disabled"),
    Input("start", "n_clicks"),
    Input("stop", "data"),
    prevent_initial_call=True,
)
def ctrl_callbak(start, s):
    ctx = callback_context
    if None is not ctx.triggered:
        tid = ctx.triggered[0]["prop_id"].split(".")[0]

        if "start" == tid and start:
            print("start")
            return no_update, False

        elif "stop" == tid:
            print("stop")
            return no_update, True

        else:
            raise PreventUpdate
    else:
        raise PreventUpdate


@callback(
    Output("stop", "data"),
    Input("start", "n_clicks"),
    prevent_initial_call=True,
)
def main_callbak(click):
    for i in range(10):
        print("Hello", i)
        time.sleep(1)
    return True


if __name__ == "__main__":
    app.run_server(debug=True)`
python callback progress-bar plotly-dash circular-dependency
1个回答
0
投票

欢迎!在这种特殊情况下,您可以使用两个单独且更简单的回调来代替

ctrl_callbak

@callback(
    Output("interval", "disabled", allow_duplicate=True),
    Input("stop", "data"),
    prevent_initial_call=True)
def on_stop_data_ready(_):
    print("stop")
    return True


@callback(
    Output("interval", "disabled", allow_duplicate=True),
    Input("start", "n_clicks"),
    prevent_initial_call=True)
def on_start_button_click(_):
    print("start")
    return False

您可能还想了解 Dash 中的 loading states

Loading
组件:

Dash 在

Loading
组件中使用此属性来在组件加载时显示微调器。这意味着您可以使用
Loading
组件来包装您想要显示加载微调器的其他组件。

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