You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Streamlit列布局与侧边栏共存时按钮状态丢失问题求助

Streamlit列布局与侧边栏共存时按钮状态丢失问题求助

这个问题我太熟悉了!Streamlit的运行机制是每次用户有任何交互操作(点按钮、改侧边栏选项等),都会从头重新执行一遍整个脚本,普通的st.button()的点击状态只能在点击后的那一次脚本运行中生效,等你操作侧边栏触发新一轮运行时,按钮状态就被重置了。

咱们用Streamlit自带的st.session_state就能完美解决这个问题,它专门用来在多次脚本运行之间保存状态数据。下面是修改后的完整代码,我还加了一些细节方便你直观看到按钮状态:

import streamlit as st

# 初始化会话状态里的按钮标记,第一次运行时创建这些变量
if 'button1_clicked' not in st.session_state:
    st.session_state.button1_clicked = False
if 'button2_clicked' not in st.session_state:
    st.session_state.button2_clicked = False
if 'button3_clicked' not in st.session_state:
    st.session_state.button3_clicked = False

# 定义按钮点击的回调函数,用来切换会话状态里的标记
def toggle_btn1():
    st.session_state.button1_clicked = not st.session_state.button1_clicked

def toggle_btn2():
    st.session_state.button2_clicked = not st.session_state.button2_clicked

def toggle_btn3():
    st.session_state.button3_clicked = not st.session_state.button3_clicked

col1, col2, col3 = st.columns([.4,.5,1])

# 保留你原来的按钮样式,还加了点击后的深色样式
m = st.markdown("""
<style>
div.stButton > button:first-child {
background-color: rgb(0,250,154);
}
div.stButton > button:first-child[data-clicked="true"] {
background-color: rgb(0,200,120);
}
</style>""", unsafe_allow_html=True)

with col1:
    # 给按钮加on_click回调,点击时触发状态切换,同时设置唯一key避免冲突
    st.button('aa', on_click=toggle_btn1, key='btn_aa')
    # 根据会话状态显示按钮是否被选中
    if st.session_state.button1_clicked:
        st.markdown("✅ 按钮aa已选中")

with col2:
    st.button('bb', on_click=toggle_btn2, key='btn_bb')
    if st.session_state.button2_clicked:
        st.markdown("✅ 按钮bb已选中")

with col3:
    st.button('cc', on_click=toggle_btn3, key='btn_cc')
    if st.session_state.button3_clicked:
        st.markdown("✅ 按钮cc已选中")

option_1 = st.sidebar.checkbox('x1', value=True)
option_2 = st.sidebar.checkbox('x2')

关键说明:

  1. 会话状态初始化:第一次运行脚本时,给st.session_state添加按钮状态变量,默认设为False(未点击)。
  2. 回调函数:每个按钮绑定一个回调,点击时切换对应会话状态变量的值(从FalseTrue,再点又变False,实现 toggle 效果)。
  3. 状态持久化:不管你怎么操作侧边栏,st.session_state里的变量都会保留,所以按钮的选中状态不会丢失,每次脚本重新运行都会根据这个状态显示对应提示。

如果你想要的是“点击一次就保持选中,不能取消”的效果,只需要把回调函数改成直接设为True就行,比如:

def set_btn1_clicked():
    st.session_state.button1_clicked = True

这样调整后,不管你怎么操作侧边栏,按钮的点击状态都会稳稳保留住啦!

备注:内容来源于stack exchange,提问作者user14269252

火山引擎 最新活动