Control st.toggle() using st.button()

I am testing a very simple streamlit app with a toggle and a button. Specifically, I want to use st.toggle and have a st.button that, when clicked, switches this toggle off. The toggle is on by default.

The problem I am facing is that the button works fine to disable the toggle on the first click. Now if I turn the toggle on manually and click the button, it does not switch the toggle off. Further, turning the toggle on/off manually is taking two mouse clicks. Is there something about session_state I am missing in my code? Thanks for any advice!

Code below with comments. Deployed locally. Python v3.12 and Streamlit v1.34.

import streamlit as st

st.title('Streamlit Toggle App')

# Initialize or retrieve the current state of the toggle
if 'toggle' not in st.session_state:
    st.session_state.toggle = True  # Default to on

# Function to switch off the toggle
def switch_off_toggle():
    st.session_state.toggle = False

# Display the toggle with its current state
toggle = st.toggle("Toggle", value=st.session_state.toggle)

# Display the button, which when clicked, will call the function to switch off the toggle
btn = st.button("Switch Off Toggle", on_click=switch_off_toggle)

# Update the toggle state based on user interaction
st.session_state.toggle = toggle

# Optional: Display the current state of the toggle
st.write("Toggle is currently:", "On" if st.session_state.toggle else "Off")

Hi @saurabh-khanna

Typically, if you’re encountering that it takes 2 clicks to see a change, it’s most likely that you’ll need to apply session state with callback function. Could you try using the switch_off_toggle function on st.toggle() and see if that works?

When you want to programmatically control widgets, use key to tie their value directly to Session State.

toggle = st.toggle("Toggle", key="toggle")
1 Like

I think this is a good way to accomplish what you’re looking for

import streamlit as st

if "toggle" not in st.session_state:
    st.session_state.toggle = True  # Default to on

if "toggle_key" not in st.session_state:
    st.session_state.toggle_key = 1


def toggle_toggle():
    st.session_state.toggle = not st.session_state[st.session_state.toggle_key]
    st.session_state.toggle_key += 1


toggle = st.toggle(
    "Toggle", value=st.session_state.toggle, key=st.session_state["toggle_key"]
)

st.button("Toggle Toggle", on_click=toggle_toggle)

One trick is that, to make sure that the user’s selection gets overridden, you actually want to change the key that is associated with the toggle, so that it gets created afresh.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.