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!
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!!
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.
Please how can i do that for this?
if st.button("Upload CSV with DateTime Column"):
st.write("IMPORT DATA")
st.write(
"Import the time series CSV file. It should have one column labelled as 'DateTime'")
data = st.file_uploader('Upload here', type='csv')
st.session_state.counter = 0
if data is not None:
dataset = pd.read_csv(data)
dataset['DateTime'] = pd.to_datetime(dataset['DateTime'])
dataset = dataset.sort_values('DateTime')
junction = st.number_input(
'Which Junction:', min_value=1, max_value=4, value=1, step=1, format='%d')
results = predict_traffic(junction, dataset['DateTime'])
st.write('Upload Sucessful')
st.session_state.counter += 1
if st.button("Predict Dataset"):
result = results
result = pd.concat([dataset, result], axis=1)
st.success('Successful!!!')
st.write('Predicting for Junction', 1)
st.write(result)
def convert_df(df):
# IMPORTANT: Cache the conversion to prevent computation on every rerun
return df.to_csv().encode('utf-8')
csv = convert_df(result)
st.download_button(
label="Download Traffic Predictions as CSV",
data=csv,
file_name='Traffic Predictions.csv',
mime='text/csv',
)
st.session_state.counter += 1
Do you have a particular reason for using a button to show the upload dialog? You could certainly do that, but it seems more natural to using something like st.expander, like so:
with st.expander("Upload CSV with DateTime Column"):
st.write("IMPORT DATA")
st.write(
"Import the time series CSV file. It should have one column labelled as 'DateTime'"
)
data = st.file_uploader("Upload here", type="csv")
st.session_state.counter = 0
if data is not None:
dataset = pd.read_csv(data)
dataset["DateTime"] = pd.to_datetime(dataset["DateTime"])
dataset = dataset.sort_values("DateTime")
junction = st.number_input(
"Which Junction:", min_value=1, max_value=4, value=1, step=1, format="%d"
)
results = predict_traffic(junction, dataset["DateTime"])
st.write("Upload Sucessful")
st.session_state.counter += 1
if st.button("Predict Dataset"):
result = results
result = pd.concat([dataset, result], axis=1)
st.success("Successful!!!")
st.write("Predicting for Junction", 1)
st.write(result)
def convert_df(df):
# IMPORTANT: Cache the conversion to prevent computation on every rerun
return df.to_csv().encode("utf-8")
csv = convert_df(result)
st.download_button(
label="Download Traffic Predictions as CSV",
data=csv,
file_name="Traffic Predictions.csv",
mime="text/csv",
)
st.session_state.counter += 1
Wow, it works like a charm.
Thanks a lot @blackary
Hi @blackary , I seem to have encountered another small problem, anytime I click on the download button, the file is downloaded and the site refreshes immediately as well
In general that’s just how streamlit inputs work, including buttons – when you change them/click on them/etc it causes the app to rerender. Other widgets should keep their state (e.g. dropdowns should stay expanded, uploaded files should stay uploaded, etc.), but sometimes this can be a problem because there is some slow/expensive calculation that you don’t want to rerun often. In that case, st.experimental_memo may be the solution. Is it causing other problems that you are trying to avoid?
It’s not really causing any problem I’m trying to avoid. So I guess I can live with it.
Once again, Thank you so much for your help.
There is a new extra in streamlit-extras version 0.2.5 which does this explicitly
@blackary, this is nice. It should be part of the main, rather than an extra.
Cheers
How can I do this with st.experimental_data_editor ? In editable table version ?
I’m not sure what you mean. This topic is about nesting buttons so I’m unclear how you want to relate that to the editable dataframe. I think you can go ahead and create a new topic with a more complete explanation of what you are trying to accomplish and what you have tried that isn’t working.
This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.
These cookies are necessary for the website to function and cannot be switched off. They are usually only set in response to actions made by you which amount to a request for services, such as setting your privacy preferences, logging in or filling in forms.
These cookies allow us to count visits and traffic sources so we can measure and improve the performance of our site. They help us understand how visitors move around the site and which pages are most frequently visited.
These cookies are used to record your choices and settings, maintain your preferences over time and recognize you when you return to our website. These cookies help us to personalize our content for you and remember your preferences.
These cookies may be deployed to our site by our advertising partners to build a profile of your interest and provide you with content that is relevant to you, including showing you relevant ads on other websites.