Hide sidebar buttons when switching tabs

Let’s say i have this small streamlit application with a sidebar that contains 4 buttons for example (Button 1, …, Button 4). And in the main panel, I have two tabs (Tab 1 and Tab 2).

Now I want this :

  • When I select Tab 1, ONLY display Button 1 and Button 2 and hide Button 3 and Button 4.
  • When I select Tab 2, ONLY display Button 3 and Button 4 and hide Button 1 and Button 2.

I tried this with session_state to store the current tab but it’s not working. Any ideas ?

import streamlit as st

def display_buttons(tab):
    if tab == "Tab 1":
        st.sidebar.button("Button 1")
        st.sidebar.button("Button 2")
    elif tab == "Tab 2":
        st.sidebar.button("Button 3")
        st.sidebar.button("Button 4")

if 'active_tab' not in st.session_state:
    st.session_state['active_tab'] = 'Tab 1'

tab1, tab2 = st.tabs(["Tab 1", "Tab 2"])

if tab1:
    st.session_state['active_tab'] = 'Tab 1'
if tab2:
    st.session_state['active_tab'] = 'Tab 2'

with tab1:
    st.write("This is Tab 1")
    if st.session_state['active_tab'] == 'Tab 1':
        display_buttons("Tab 1")

with tab2:
    st.write("This is Tab 2")
    if st.session_state['active_tab'] == 'Tab 2':
        display_buttons("Tab 2")

Unfortunately, st.tabs is purely a visual organization component, it doesn’t actually change which parts of your app runs. In your case,

if tab1:
    st.session_state['active_tab'] = 'Tab 1'
if tab2:
    st.session_state['active_tab'] = 'Tab 2'

will always end up showing active_tab = Tab 2, because it will run the first, then the second.

And

with tab1:
    st.write("This is Tab 1")
    if st.session_state['active_tab'] == 'Tab 1':
        display_buttons("Tab 1")

with tab2:
    st.write("This is Tab 2")
    if st.session_state['active_tab'] == 'Tab 2':
        display_buttons("Tab 2")

will do the same. The contents of the tab will be different, but the behavior of display_buttons won’t be any different.

If you want an alternative to st.tabs that actually programmatically changes what runs, you might consider st.pills - Streamlit Docs

It’s not exactly the same as tabs (e.g. you can deselect all of the buttons so none is selected), but it’s similar

import streamlit as st


def display_buttons(tab):
    if tab == "Tab 1":
        st.sidebar.button("Button 1")
        st.sidebar.button("Button 2")
    elif tab == "Tab 2":
        st.sidebar.button("Button 3")
        st.sidebar.button("Button 4")


if "active_tab" not in st.session_state:
    st.session_state["active_tab"] = "Tab 1"

tab = st.pills("", ["Tab 1", "Tab 2"], default="Tab 1", selection_mode="single")

if tab == "Tab 1":
    display_buttons("Tab 1")
elif tab == "Tab 2":
    display_buttons("Tab 2")
1 Like

Thank you!

1 Like

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