Streamlit输入测试题答案时页面重置循环问题求助
Streamlit测试页面重置问题解决方案
问题根源
Streamlit的运行机制是每次用户交互都会重新执行整个脚本,你的代码没有通过st.session_state跟踪当前应用所处的阶段(候选人信息填写/测试答题)。所以当你在测试题输入框中输入内容时,页面重绘后脚本会重新执行main()函数,回到初始的信息填写界面。
解决方案
通过st.session_state管理应用状态,标记当前所处阶段,同时保存候选人信息、答题内容等关键数据,避免重绘时丢失状态。
修改后的完整代码
import streamlit as st import pandas as pd def main(): st.title('Employer Test') # 初始化会话状态变量 if 'stage' not in st.session_state: st.session_state['stage'] = 'info' # info: 信息填写阶段, test: 测试阶段, completed: 测试完成 if 'full_name' not in st.session_state: st.session_state['full_name'] = "" if 'answers' not in st.session_state: st.session_state['answers'] = [""] * 3 # 信息填写阶段 if st.session_state['stage'] == 'info': st.markdown('## Candidate Information') # 绑定输入到session_state,避免重绘丢失 st.session_state['full_name'] = st.text_input('Full Name', value=st.session_state['full_name']) experience = st.selectbox("Experience", ["Fresher"], index=0) language = st.selectbox("Language", ["Python"], index=0) if st.button('Submit'): if st.session_state['full_name']: st.session_state['stage'] = 'test' # 切换到测试阶段 st.rerun() # 立即重绘页面,显示测试内容 # 测试答题阶段 elif st.session_state['stage'] == 'test': run_python_test() # 测试完成阶段 elif st.session_state['stage'] == 'completed': st.success("测试已完成,结果已保存!") def run_python_test(): st.title('Python Test') questions = [ { 'question': 'What is the output of the following code?\n\n```python\nx = 5\nprint(x)\n```', 'options': ['5', '10', '0', 'Error'], 'correct_answer': '5' }, { 'question': 'Which of the following is a Python data type?', 'options': ['List', 'Streamlit', 'GitHub', 'HTML'], 'correct_answer': 'List' }, { 'question': 'What is the result of the expression 3 + 7 * 2?', 'options': ['13', '20', '17', 'Error'], 'correct_answer': '17' } ] total_questions = len(questions) score = 0 # 显示题目并绑定输入到session_state for i, question_data in enumerate(questions): st.write(f'Question {i+1}: {question_data["question"]}') st.session_state['answers'][i] = st.text_area( f"Enter answer for Question {i+1}", value=st.session_state['answers'][i], key=f"answer_{i}" ) if st.button("Submit Test", key="submit_test"): # 计算分数 for i, ans in enumerate(st.session_state['answers']): if ans.strip() == questions[i]['correct_answer']: score += 1 st.write(f"Question {i+1} Answer: {ans}") percentage_score = (score / total_questions) * 100 st.write(f"Your score: {percentage_score}%") if percentage_score >= 60: save_result(st.session_state['full_name'], percentage_score) st.session_state['stage'] = 'completed' st.rerun() def save_result(full_name, score): data = {'Full Name': [full_name], 'Score': [score]} df = pd.DataFrame(data) # 追加写入而不是覆盖,避免之前的结果丢失 df.to_csv('test_results.csv', mode='a', header=not pd.io.common.file_exists('test_results.csv'), index=False) st.write('Result saved successfully!') if __name__ == '__main__': main()
关键改动说明
- 状态管理:用
st.session_state['stage']标记当前所处阶段,确保页面重绘后能保持在正确的界面。 - 数据持久化:将候选人姓名、答题内容绑定到
st.session_state,避免交互时丢失输入内容。 - 页面切换:使用
st.rerun()在状态切换后立即重绘页面,确保用户能看到对应阶段的内容。 - 结果保存优化:修改CSV写入逻辑为追加模式,避免覆盖之前的测试结果。
内容的提问来源于stack exchange,提问作者Dharniesh P R
相关产品推荐
相关产品推荐

