streamlit widget dependency
Asked Answered
B

2

5

I am trying a simple concept of two widgets, where one is dependent on the other

I want to user to click a button, that opens up a number slider. The user then has the option to select the number through number slider.

Here is the code I am using

import streamlit as st
press_button = st.button("Press it Now!")
if press_button :
    # ask for the value
    th = st.number_input("Please enter the values from 0 - 10",)

The issue I face is the moment I change the number slider's value, streamlit reruns the entire thing, and one has to push the "button" again to get back to the number slider. Ultimately, the number slider never changes

Boyar answered 22/10, 2020 at 21:2 Comment(0)
R
6

Streamlit reruns a script every time an action occurs: a button is pressed, a number is input, etc. To save a value, use a cached function to maintain values between runs.

I'm pretty sure this is what you want:

import streamlit as st

# Keep the state of the button press between actions
@st.cache_resource
def button_states():
    return {"pressed": None}

press_button = st.button("Press it Now!")
is_pressed = button_states()  # gets our cached dictionary

if press_button:
    # any changes need to be performed in place
    is_pressed.update({"pressed": True})

if is_pressed["pressed"]:  # saved between sessions
    th = st.number_input("Please enter the values from 0 - 10")

Note: you said you wanted a slider, but then you used a number input. If you actually wanted a number slider, use
st.slider("Select a Number", min_value=1, max_value=10, step=1)

A few extra things to consider:

  1. If you want the number input to guaranteed appear directly beneath the button, you will need to create a place holder near the top of your script:
  btn = st.empty()
  nmb = st.empty()

This guarantees that nmb will appear directly beneath btn. And when you define your widgets, instead of calling st.button(...) you call btn.button(...).

  1. If you want to create a toggle button (when you click it again, the number input disappears), you can do so by using
  if press_button:
      is_pressed.update({"pressed": not is_pressed["pressed"]})
  1. If you want the button to disappear after you press it, use
  if is_pressed["pressed"]:f
      btn.empty()
      th = nmb.number_input(...)
Riparian answered 27/10, 2020 at 2:19 Comment(1)
Can I use the slider input value to perform other actions without resetting the app?Facing
B
0

There seems to be a workaround as the button widget returns a boolean. When I used the check box, I got what I wanted:

import streamlit as st
    press_button = st.checkbox("Press it Now!")
    if press_button :
        # ask for the value
        th = st.number_input("Please enter the values from 0 - 10",)
Boyar answered 23/10, 2020 at 15:32 Comment(1)
this does not answer the question. if the button gets unpressed, 'th' is reset to the default valueRudnick

© 2022 - 2024 — McMap. All rights reserved.