Values disappear after using button in streamlit

Question:

I am trying to write an application to play Wheel of Fortune. Once I draw a password and want to e.g. draw points the password disappears. I know that this is caused by refreshing the application after pressing another button, but I do not know how to stop it.

This is how my code looks like.

import streamlit as st
import random

# Create a list containing the letters in a word
def lista_slowo(slowo):
    slowo = slowo.lower()
    lista_slowo = []
    for litera in slowo:
        lista_slowo.append(litera)
    return lista_slowo

# Create an empty list to display
def pusta_lista_na_tablicy(slowo):
    pusta_lista_na_tablicy = []
    for litera in slowo:
        pusta_lista_na_tablicy.append("_")
    return pusta_lista_na_tablicy

# Converting a list to a string
def zamien_na_stringa(lista_na_tablicy):
    napis = ""
    for x in lista_na_tablicy:
        napis = napis + x + " "
    return napis

st.sidebar.title("Koło fortuny")
st.sidebar.text("Witamy w grze Koło Fortuny.")
st.sidebar.text("Wybierz liczbę graczy.nNastępnie kliknij przycisk 'Losuj kategorię'.")

slownik_kategorii = {"Zwierzęta":["Krowa","Kura","Koń"],
             "Owoce":["Mandarynka","Pomarańcza","Truskawka"],
             "Warzywa":["Ogórek","Marchewka","Sałata"],
             "Ubrania":["Spodnie","Koszulka","Koszula"],
            "Pojazdy":["Samochód","Motocykl","Samolot"]}

slownik_wartosci = [100,200,300,400,500,600,700,800,900,1000,1500,0]



ilosc_graczy = st.sidebar.selectbox("Wybierz ilość graczy",[1,2])

losuj = st.sidebar.button("Losuj kategorię")

kategoria = st.subheader("")

if losuj:
    kategoria = random.choice(list(slownik_kategorii))
    st.subheader(f"Kategoria: {kategoria}")
    slowo = random.choice(slownik_kategorii[kategoria])
    lista_na_tablicy = pusta_lista_na_tablicy(slowo)
    napis = zamien_na_stringa(lista_na_tablicy)
    st.title(napis)

    st.text("Słowo do odgadnięcia " + slowo)


odgaduj = st.sidebar.button("Odgadnij hasło")
krec = st.sidebar.button("Kręć kołem")
podaj_litere = st.sidebar.button("Podaje spółgłoskę")

if krec:
    wartosc = random.choice(slownik_wartosci)
    st.sidebar.text("Wartość spółgłoski: " + str(wartosc) + " zł")

if podaj_litere:
    podana_litera = ""
    podana_litera = st.sidebar.text_input("Wpisz spółgłoskę")
    st.sidebar.text(podana_litera)

I tried to replace the password generation button with a radio, but then every time you click another button the password draw from scratch

Asked By: mlodycezar

||

Answers:

1. Buttons don’t retain state

Check out these similar questions/answers: here and here
And this blog post I mentioned in both: here

Buttons do not retain state. They return True on the page load
resulting from their click and then immediately go back to False. If
you nest something inside a button, it will go away as soon as the
user does something (because the page reloads and the button becomes
false).

You can store a dictionary in session state to track if buttons are clicked so your conditionals don’t revert to False.

Here’s a simple example for general applicability:

import streamlit as st

if 'clicks' not in st.session_state:
    st.session_state['clicks'] = {}

def click(key):
    st.session_state.clicks[key] = True

def unclick(key):
    st.session_state.clicks[key] = False

def button_set(i):
    left, right = st.columns(2)
    left.button(f'Button {i}', on_click=click, args=(f'button{i}',))
    if st.session_state.clicks.get(f'button{i}', False):
        left.write(f'Button {i} was clicked!')
        st.slider(f'Slider {i}', key=f'slider{i}')
        right.button(f'Reset Button {i}', on_click=unclick, args=(f'button{i}',))

for i in range(3):
    button_set(i)

st.write(st.session_state)

2. Use session state to preserve random generation between reruns

Since Streamlit reruns with every interaction, care needs to be taken with random selection. In general, save any random generation to session state so that you can control when it is regenerated.

import streamlit as st
import random

animals = ['dog', 'cat', 'bird', 'fish', 'turtle', 'rabbit', 'hamster', 'snake', 'lizard', 'frog']

if 'my_pet' not in st.session_state:
    st.session_state.my_pet = random.choice(animals)

st.write(f"My pet is a {st.session_state.my_pet}.")

def change_pet():
    st.session_state.my_pet = random.choice(animals)

st.button("Change my pet", on_click=change_pet)

st.button('Do nothing')
st.slider('Move me', 0, 100)

3. Text display widgets have no output

This line doesn’t make sense:
kategoria = st.subheader("")

Answered By: MathCatsAnd
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.