I've the following code
def drawBtn():
option= ...
st.button("Find", on_click= onSearch, args= [option])
def onSearch(opt):
# do something and then...
st.success("Done!")
drawBtn()
The problem here is that the message "Done" is insert at the top of the page instead of at the end. This problem appear only if i use on_click function. If i change it with if st.button(...): it work as i expect
Why using on_click function seems like moving the pointer of the page at the beginning?
Searching on the internet i saw always function that set only variables in st.session_state. So another question is: can I do something else inside a on_click function different to set session_state variables? Because If I try to add something else, that content is drawn always at the beginning of the page
Streamlit reruns your script on every interaction (like pressing the button). When you press the button, your entire script will be executed again but this time, st.button
will return True
, allowing you to do if st.button(...):
, which executes the code in the if
block right after the button appears.
When you use on_click
, the script will still be rerun. The function that you passed to on_click
will be executed before the script, at the beginning of the run, not after the button. So, naturally, any element that you generate in that callback will appear before other elements, since they weren't regenerated in this run yet.
Here is a link to a thread on Streamlit forums where this is discussed: link.
Can I do something else inside a on_click function different to set session_state variables?
Yes, you can use it to do anything. But it will run before anything else, you have to keep that in mind. If you don't want that, you can either use if st.button(...):
instead or use it to set session state variables to trigger some conditional code in a different part of the script.
Here is a nice use case for on_click
: after pressing the button, we want something to appear before it. on_click
is used to set the variable right away, before we even get to the button and notice that it returned True
this time (You can use the key
parameter of st.button
to achieve a similar effect, creating a session state variable that you can use before you get to the button in this run).
if "clicked" not in st.session_state:
st.session_state["clicked"] = False
def drawBtn():
option= ...
st.button("Find", on_click= onSearch, args= [option])
def onSearch(opt):
st.session_state["clicked"] = True
if st.session_state["clicked"]:
st.success("Done!")
drawBtn()