如何在Streamlit中仅在耗时操作期间禁用按钮
解决Streamlit中耗时操作期间禁用按钮的问题
环境
- Python 3.12.2
- Streamlit 1.33.0
需求
点击按钮触发耗时操作时,按钮立即禁用;操作完成后,按钮恢复启用状态。
原代码(无法实现需求)
import time import streamlit as st import streamlit.components.v1 as stc def expensive_process(): time.sleep(3) return 123 def main(): st.session_state.disabled = False text_wait = st.empty() but_ph = st.empty() but = but_ph.button('calculate', disabled=st.session_state.disabled) if but: st.session_state.disabled = True text_wait.markdown('running...') result = expensive_process() st.session_state.disable = False text_wait.markdown(f'The result was {result}') if __name__ == '__main__': main()
问题分析
- 每次运行
main()都会重置st.session_state.disabled = False,覆盖之前的状态设置,导致按钮无法保持禁用。 - 拼写错误:
st.session_state.disable = False应为st.session_state.disabled = False。 - Streamlit基于脚本重运行机制,点击按钮后需要触发页面刷新才能更新按钮状态,原代码中设置
disabled=True后没有触发刷新,用户看不到按钮禁用的状态。
解决方案
利用Streamlit的session_state持久化状态,结合st.rerun()触发页面刷新,实现按钮的动态禁用/启用:
import time import streamlit as st def expensive_process(): time.sleep(3) return 123 def main(): # 初始化session_state,仅第一次运行时设置 if 'disabled' not in st.session_state: st.session_state.disabled = False text_wait = st.empty() but_ph = st.empty() # 渲染按钮,绑定session_state的disabled状态 but = but_ph.button('calculate', disabled=st.session_state.disabled) if but: # 设置按钮禁用状态,触发页面刷新 st.session_state.disabled = True st.rerun() # 检查是否处于运行状态,执行耗时操作 if st.session_state.disabled: text_wait.markdown('running...') result = expensive_process() # 操作完成后恢复按钮状态,再次刷新页面 st.session_state.disabled = False text_wait.markdown(f'The result was {result}') st.rerun() if __name__ == '__main__': main()
关键说明
- 初始化session_state时用
if 'disabled' not in st.session_state,避免每次运行都重置状态。 - 点击按钮后先设置
disabled=True并调用st.rerun(),让页面刷新后按钮显示禁用状态。 - 单独分支处理耗时操作,确保操作期间按钮保持禁用,完成后再恢复状态并刷新页面。
内容的提问来源于stack exchange,提问作者dixhom
相关产品推荐
相关产品推荐

