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

"Circular Dependencies" but works perfectly; How to fix it

提问人:YaOo 提问时间:9/24/2023 最后编辑:YaOo 更新时间:9/29/2023 访问量:66

问:

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

  1. 第一个回调生成带有 .dcc.interval
  2. 第二个回调控制活动的启动和停止。
  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 回调 progress-bar plotly-dash circular-dependency

评论


答:

0赞 Dmitry 9/29/2023 #1

欢迎!在这种特殊情况下,您可以使用两个独立且更简单的回调来代替: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

Dash 在组件中使用此道具来显示组件是否正在加载微调器。这意味着您可以使用该组件来包装要显示其加载微调框的其他组件。LoadingLoading

评论

0赞 YaOo 10/2/2023
非常感谢您的回答。你让我的代码在没有循环依赖的情况下工作。我不知道可以复制输出,在整理文档后,我发现自 2.9 破折号版本以来它是可能的。迎接新闻!再次感谢您的帮助。