3+ Nested Buttons

Hello!

I am new to streamlit. I was wondering if there was a way to nest 3+ buttons, not only 2? I have only seen examples for 2. Thank you! If someone could make a simple example that would also be great. Thank you!

Hello, @GriffinF, welcome to the forum!

Here’s one way to work it, by using session state as the source of truth, and treating each button as a toggle for the session state.

Code:

import streamlit as st

# This doesn't work, because button "pressed" state doesn't survive rerun, and pressing
# any button triggers a rerun.

st.write("# This doesn't work:")

if st.button("Button1_take1"):
    if st.button("Button2_take1"):
        if st.button("Button3_take1"):
            st.write("Button3")

# So, instead, we use session state to store the "pressed" state of each button, and
# make each button press toggle that entry in the session state.

st.write("# This works:")

if "button1" not in st.session_state:
    st.session_state["button1"] = False

if "button2" not in st.session_state:
    st.session_state["button2"] = False

if "button3" not in st.session_state:
    st.session_state["button3"] = False

if st.button("Button1"):
    st.session_state["button1"] = not st.session_state["button1"]

if st.session_state["button1"]:
    if st.button("Button2"):
        st.session_state["button2"] = not st.session_state["button2"]

if st.session_state["button1"] and st.session_state["button2"]:
    if st.button("Button3"):
        # toggle button3 session state
        st.session_state["button3"] = not st.session_state["button3"]

if st.session_state["button3"]:
    st.write("**Button3!!!**")


# Print the session state to make it easier to see what's happening
st.write(
    f"""
    ## Session state:
    {st.session_state["button1"]=}

    {st.session_state["button2"]=}

    {st.session_state["button3"]=}
    """
)

To see it in action:
https://playground.streamlitapp.com/?q=triple-button

Hey, this is super awesome, thank you!!

1 Like

Hey, I was also wondering if there was a way for example: if you click button 1, x = ‘hi’, to carry that to button 2 and if button 2 was clicked you can st.write(x). Something along those lines.

That works exactly like you’d expect. Pseudocode:

x = “”

if button 1 clicked:
x = “hi”

if button 2 clicked:
st.write(x)

That should work just as you expect it to. In general, other than cases of using st.session_state or st.experimental_cache, you can think of a streamlit app as a script that just runs from top to button, but also is affected by the widget states.

Hopefully that’s helpful.