Streamlit会话状态批量加载引发DuplicateWidgetID错误的解决
解决是非题答题游戏的DuplicateWidgetID错误
核心问题原因
循环批量创建交互组件时,所有提交按钮使用了相同的submit_answer作为key值,框架会将同一key的组件判定为重复实例,触发ID冲突错误。
具体解决方案
1. 为每个组件生成唯一Key
遍历问题时,将问题的索引或唯一ID拼接进组件key中,确保每个按钮的标识独一无二:
# 假设questions是包含问题内容、正确答案的列表 for idx, question in enumerate(questions): st.write(f"问题{idx+1}:{question['content']}") user_answer = st.radio("请选择答案", ["是", "否"], key=f"answer_{idx}") # 用问题索引拼接key,避免重复 if st.button("提交答案", key=f"submit_answer_{idx}"): # 即时对错反馈逻辑 if user_answer == question['correct_answer']: st.success("回答正确!") st.session_state['score'] += 1 else: st.error(f"回答错误,正确答案是{question['correct_answer']}")
2. 用会话状态实现单题流式展示
如果需求是逐个答题,通过会话状态记录当前答题进度,每次只渲染当前问题的组件,从根源避免重复key:
# 初始化会话状态 if 'current_q_idx' not in st.session_state: st.session_state['current_q_idx'] = 0 st.session_state['score'] = 0 # 示例问题列表 questions = [ {"content": "地球是太阳系的中心?", "correct_answer": "否"}, {"content": "标准大气压下水的沸点是100℃?", "correct_answer": "是"}, # 更多问题... ] current_question = questions[st.session_state['current_q_idx']] st.write(f"问题{st.session_state['current_q_idx']+1}:{current_question['content']}") user_answer = st.radio("请选择答案", ["是", "否"], key="current_answer") if st.button("提交答案"): # 即时反馈 if user_answer == current_question['correct_answer']: st.success("回答正确!") st.session_state['score'] += 1 else: st.error(f"回答错误,正确答案是{current_question['correct_answer']}") # 切换下一题或结束答题 if st.session_state['current_q_idx'] < len(questions)-1: st.session_state['current_q_idx'] += 1 st.experimental_rerun() # 自动刷新页面加载下一题 else: st.write(f"答题结束!最终得分:{st.session_state['score']}/{len(questions)}")
3. 额外注意事项
- 不要在循环中使用固定值作为组件
key,必须绑定问题的唯一标识 - 利用会话状态变量控制渲染范围,避免一次性生成所有问题的交互组件
- 若需保留历史答题记录,可在会话状态中维护
answered_records列表,存储已答问题的结果
内容的提问来源于stack exchange,提问作者Aragon
相关产品推荐
相关产品推荐

