Streamlit multiple nested buttons, not working

35 views Asked by At

I am trying to implement streamlit UI and two mutually exclusive operation button. each operation has nested streamlit buttons. The buttons behavior should be like if i click on one button, than another should be reset, also if i repeat clicking button, operations and nested buttons of that particular button should be visible and working for that perticular button only. I tried multiple approaches. i solved nested button problem using st.session state. but when i select second button after clicking on first button, content from first button is still there, which i dont expect . vice versa. please help me to solve this

sideb=st.sidebar
button1 = sideb.button('Single')
if st.session_state.get('button') != True:

    st.session_state['button'] = button1 # Saved the state

if st.session_state['button'] == True:

    st.write("button1 is True")

    option=st.selectbox('Select App?',
            ('A', 'B', 'C'),index=0)

     
    st.write('You selected:', option)
    option=option.lower()
    ''''SOME CHATTING APP WITHOUT ANY BUTTON '''
button2 = sideb.button('Multiple Queries')
if st.session_state.get('button2') != True:

    st.session_state['button2'] = button2 # Saved the state

if st.session_state['button2'] == True:
    uploaded_file = st.file_uploader("Choose a file with app_name and list_of questions.", type=['xlsx'], accept_multiple_files=False)
    st.write("button2 is True")
    if uploaded_file is not None:
        stqdm.pandas()
        df=pd.read_excel(uploaded_file)
    if st.button('Generate'):
        st.write("Do your logic here")
     
        with st.spinner('Wait for it...'):
            df['Answers']=df.progress_apply(qs, axis=1)
            AgGrid(df)
        st.success('Done!')
        csv = convert_df(df)
        download2 = st.download_button(
            label="Download Answers",
            data=csv,
            file_name='Answers.csv',
            key='download-csv'
        )
1

There are 1 answers

0
AlGM93 On

I am not 100% if what you intend but from what I have understood I believe you want to achieve some kind of switch kind of behaviour. The easiest and cleanest way to do that in Streamlit is by implementing callbacks on the buttons to change the state of your session. Callbacks are fuctions that are triggered when a button is clicked.

import streamlit as st

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

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

def switch_button1_state():
    st.session_state['button1'] = True
    st.session_state['button2'] = False

def switch_button2_state():
    st.session_state['button1'] = False
    st.session_state['button2'] = True

sideb=st.sidebar
button1 = sideb.button('Single', on_click=switch_button1_state)
button2 = sideb.button('Multiple Queries', on_click=switch_button2_state)


if st.session_state['button1'] == True:
    st.write("Single logic here")

if st.session_state['button2'] == True:
    st.write("Multiple Queries logic here")

Here every time you click a button you flip the state of both buttons in a mutually exclusive way, allowing the control flow to display one branch or the other but not both at the same time. If this is not the intended end result please provide clarifications.