Reputation: 57
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
Upvotes: 1
Views: 3572
Reputation: 861
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)
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)
This line doesn't make sense:
kategoria = st.subheader("")
Upvotes: 2