Streamlit应用仅执行一轮后挂起循环的问题排查与修复
问题分析与修复方案
核心问题总结
- 全局变量
key_dict无法跨Streamlit会话刷新保留状态 - 点击Submit/Reset后,
st.session_state.clicked中的对应状态未重置,导致后续逻辑持续触发 - 错误使用
pyautogui强制刷新,破坏Streamlit的状态管理机制 - 缺少必要的模块导入(
random、string、pathlib.Path)
修复后的完整代码
import streamlit as st import random import string from pathlib import Path # 初始化会话状态 if 'clicked' not in st.session_state: st.session_state.clicked = {"submit": False, "reset": False} if 'input_keys' not in st.session_state: st.session_state.input_keys = [random.choice(string.ascii_uppercase) + str(random.randint(0, 999999))] if 'key_dict' not in st.session_state: st.session_state.key_dict = {} # 更新按钮状态的函数 def update_button_state(button): st.session_state.clicked[button] = True def sidebar_section(): c1, c2 = st.sidebar.columns(2) c1.write("Main Area") # 添加新行按钮 if c2.button("Add New Row"): new_key = random.choice(string.ascii_uppercase) + str(random.randint(0, 999999)) st.session_state.input_keys.append(new_key) h1, h2 = st.sidebar.columns(2) index = 1 current_key_dict = {} # 渲染所有键值对输入框并收集数据 for input_key in st.session_state.input_keys: key_val = h1.text_input(f"Input 1 {index}", placeholder="Enter Key", key=input_key) val_val = h2.text_input(f"Input 2 {index}", placeholder="Enter Value", key=f"{input_key}_input") if key_val: # 仅当键不为空时存入字典 current_key_dict[key_val] = val_val index += 1 # 更新会话状态中的字典 st.session_state.key_dict = current_key_dict return current_key_dict # 侧边栏组件 file = st.sidebar.file_uploader('Upload', type=["pdf", "txt"]) key_dict = sidebar_section() st.sidebar.markdown("---") c1, c2 = st.sidebar.columns([1, 1]) c1.button("Reset", on_click=update_button_state, args=["reset"], use_container_width=True) c2.button("Submit", on_click=update_button_state, args=["submit"], use_container_width=True) # 重置逻辑 if st.session_state.clicked["reset"]: # 重置输入行和状态 st.session_state.input_keys = [random.choice(string.ascii_uppercase) + str(random.randint(0, 999999))] st.session_state.key_dict = {} # 重置按钮状态,避免重复触发 st.session_state.clicked["reset"] = False # 强制页面刷新(使用Streamlit原生方式) st.rerun() # 提交逻辑 if st.session_state.clicked["submit"]: print("Inside Submit buttons \n") if file is not None: save_folder = '.' save_path = Path(save_folder, file.name) with open(save_path, mode='wb') as w: w.write(file.getvalue()) print(f"length of Key Dict = {len(key_dict)}") with st.spinner("Loading Results ! "): print("Inside Generate button and Uploaded file is not none. Going to get results \n") # 这里添加你的本地计算逻辑 # 显示结果示例 st.write("### 提交结果") st.write("上传文件已保存") st.write("键值对数据:", key_dict) # 重置提交按钮状态,避免重复触发 st.session_state.clicked["submit"] = False
关键修复点说明
- 会话状态管理优化:将
key_dict移至st.session_state中,确保跨刷新保留数据;每次渲染输入框时重新构建字典,保证数据实时同步 - 按钮状态重置:在Submit/Reset逻辑执行完成后,立即将对应状态设为
False,避免后续页面刷新时重复触发相同逻辑 - 移除外部刷新工具:替换
pyautogui强制刷新为Streamlit原生的st.rerun()方法,符合框架的状态管理机制 - 补全模块导入:添加了
random、string、pathlib.Path的导入,修复代码运行报错 - 输入数据有效性处理:仅当键输入框不为空时才存入字典,避免无效空键占用数据
- 代码结构优化:调整了函数命名(
clicked改为update_button_state),提升代码可读性
内容的提问来源于stack exchange,提问作者user2966197
相关产品推荐
相关产品推荐

