Streamlit中st.Text_input回车与st.Button点击同输入逻辑异常问题
问题解决:Streamlit点击提交按钮后内容显示随即清空
问题原因
你的代码中,点击按钮时会触发两次submit函数:
- 按钮的
on_click回调先执行:将st.session_state.my_text设为输入框内容,然后清空st.session_state.widget。 - 脚本重新运行时,输入框因为
widget的值从非空变为空,触发了on_change回调,再次执行submit函数。此时widget已经是空值,导致my_text被覆盖为空,最终显示的内容被清空。
而按回车键时,输入框的on_change回调只执行一次:设置my_text并清空输入框,不会触发额外的回调,所以正常工作。
解决方案一:区分回调触发源
修改submit函数,通过传递参数区分是输入框回车触发,还是按钮点击触发,仅在合适时机清空输入框:
import streamlit as st if "my_text" not in st.session_state: st.session_state.my_text = "" def submit(trigger_source): st.session_state.my_text = st.session_state.widget # 仅当按钮触发时清空输入框 if trigger_source == "button": st.session_state.widget = "" # 输入框回车触发,暂不清空输入框 st.text_input("Enter text here", key="widget", on_change=submit, args=("input",)) # 按钮点击触发,设置内容并清空输入框 st.button("Submit", on_click=submit, args=("button",)) my_text = st.session_state.my_text st.write(my_text)
解决方案二:使用Streamlit表单(更简洁)
用st.form包裹输入框和按钮,统一处理回车和按钮提交逻辑,从根源避免回调冲突:
import streamlit as st if "my_text" not in st.session_state: st.session_state.my_text = "" def submit(): st.session_state.my_text = st.session_state.widget st.session_state.widget = "" with st.form(key="text_form"): st.text_input("Enter text here", key="widget") # 表单提交按钮,按回车或点击按钮都会触发提交 st.form_submit_button(label="Submit", on_click=submit) st.write(st.session_state.my_text)
这种方法符合Streamlit设计逻辑,表单内的输入框按回车会自动触发表单提交,无需额外绑定on_change,彻底解决重复回调问题。
内容的提问来源于stack exchange,提问作者imtryin2code
相关产品推荐
相关产品推荐

