You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在执行耗时任务时临时禁用Submit按钮并完成后启用?

实现Dash按钮点击后临时禁用并执行耗时任务

当然可以实现你要的效果——点击按钮后立即禁用,执行耗时任务,完成后自动恢复启用状态。核心是要把耗时任务放到后台线程执行,避免阻塞Dash的主线程,同时通过状态存储跟踪任务进度,触发按钮状态更新。

下面是完整的实现代码:

import dash
from dash import Dash, html, dcc, Input, Output, State, callback
import dash_bootstrap_components as dbc
import threading
import time

app = Dash(__name__, external_stylesheets=[dbc.themes.BOOTSTRAP])

app.layout = html.Div([
    dbc.Button('Clickme', id='btn', disabled=False),
    # 用dcc.Store存储任务完成状态,避免全局变量的多用户冲突
    dcc.Store(id='task-status', data={'completed': False})
])

@callback(
    Output("btn", "disabled"),
    Output("task-status", "data"),
    Input("btn", "n_clicks"),
    State("btn", "disabled"),
    prevent_initial_call=True  # 避免页面加载时触发回调
)
def start_task_and_disable_btn(n_clicks, disabled):
    # 仅在按钮未禁用时执行逻辑
    if not disabled:
        # 定义后台执行的耗时任务
        def background_task():
            # 替换成你的实际计算逻辑,这里用sleep模拟耗时
            time.sleep(5)
            # 任务完成后更新状态存储,并触发回调更新按钮
            app.callback_context.outputs_list[1]['value']['completed'] = True
            dash.callback_context.triggered_id = 'task-status'
            app.run_callback(update_btn_status, [{'prop_id': 'task-status.data', 'value': {'completed': True}}])
        
        # 启动后台线程
        threading.Thread(target=background_task).start()
        # 立即返回禁用状态,同时初始化任务状态
        return True, {'completed': False}
    # 如果按钮已禁用,不做任何更新
    return dash.no_update

@callback(
    Output("btn", "disabled", allow_duplicate=True),  # 允许同一个Output被多个回调更新(Dash 2.7+支持)
    Input("task-status", "data"),
    prevent_initial_call=True
)
def update_btn_status(task_status):
    # 任务完成后,恢复按钮启用状态
    if task_status['completed']:
        return False
    return dash.no_update

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

关键说明:

  • 后台线程处理耗时任务:直接在回调里执行耗时任务会阻塞Dash主线程,导致页面无响应。用threading.Thread把任务放到后台,保证页面交互正常。
  • 状态存储跟踪进度:用dcc.Store存储任务完成状态,比全局变量更安全,适合多用户场景。
  • 分阶段更新按钮状态:
    1. 点击按钮后,第一个回调立即返回True禁用按钮,同时启动后台任务。
    2. 后台任务完成后,更新dcc.Store的状态,触发第二个回调返回False,重新启用按钮。
  • 回调配置:prevent_initial_call=True避免页面加载时误触发;allow_duplicate=True允许同一个按钮的disabled属性被两个回调更新(需Dash 2.7及以上版本)。

内容的提问来源于stack exchange,提问作者Kai-Chun Lin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 02:50:33