How to use a python generator to work with st.image, st.selectbox and st.button at the same time without reloading?

Hello all,
I’m Rohan. I’m working on a project that requires me to load a list of images from the file, display them one by one ( Changed through a click of a button like “Next Image” ) and record some pre-set information about the image from a widget like st.selectbox to a Dictionary. The problem here is that whenever I click the next button ( through st.button ) the session reloads and it starts from the beginning. Is there a workaround or some other implementation of this? Please help.

Thanks
Rohan

1 Like

Hi @R0han could you share your code and what you have already tried? It sounds like a perfect use case for st.session_state

Hello Tom, thank you for the response.

import streamlit as st
import os 


# read list of images
img_list = os.listdir('./images')
st.write(img_list)

st.title('Read Data Test')
st.markdown('***')

# empty dictionary
REGION_OF_INTEREST = {}

# Slot to overwrite the image at one place
slot = st.empty()
form_slot = st.empty()
for img in img_list:
    with form_slot.form(f'Image shown{img}'):
        slot.image(os.path.join('./images',img)) 
        roi = st.selectbox('Select the Region of Interest from the Image',['Coffee','Nintendo','Baguette','Hanky','Mask'],key=f'choices{img}')
        submitted = st.form_submit_button(f"Submit Data for {img}")
    
    if not submitted:
        st.stop()

    else:
        st.markdown(f'**READING {img} - {roi}**')
        REGION_OF_INTEREST[img] = roi     
        


st.markdown('REGION OF INTEREST')
st.write(REGION_OF_INTEREST)
    

Required Functionality
I’m trying to read a bunch of pictures from the from a folder which has, lets say, a lot of different objects with a cross hair on a single object. ( see the attached image ), the user will then need to select a predefined option from the select box and that will be read into a dictionary with key being the image name and his selection from the selectbox. I’ve also tried using generators and use next() in combination with the st.button to traverse through the images and read data simultaneously but the button resets the environment.

Expected Flow
What I’m trying to do is, operate an iteration where it reads the images from the file ( one by one ), shows it using st.image, for each image the set of options in the selectbox remains the same the only thing that changes is the picture.

Reference Image

the list of options will be like this st.selectbox(‘label’, [‘Coffee’,‘Nintendo’,‘Baguette’,‘Hanky’,‘Mask’], key=‘somekey’)

Thanks
Rohan

To address this issue, it’s important to know that Streamlit operates by running app recalculations, or reruns from the top down. This feature is a defining aspect of Streamlit and some users love it while others struggle with it. In your code you can benefit from app recalculation by using counters and callbacks:

img_list = os.listdir("./images")
st.write(img_list)
st.title("Read Data Test")
st.markdown("***")


def callback():
    if st.session_state["counter"] < len(img_list) - 1:
        st.session_state["counter"] += 1
    st.session_state["REGION_OF_INTEREST"][img] = st.session_state["selection"]

# empty dictionary
if "REGION_OF_INTEREST" not in st.session_state:
    st.session_state["REGION_OF_INTEREST"] = {}
if "counter" not in st.session_state:
    st.session_state["counter"] = 0

img = img_list[st.session_state["counter"]]

st.image(os.path.join("./images", img))
form = st.form(f"Image shown{img}")
form.selectbox(
    "Select the Region of Interest from the Image",
    ["Coffee", "Nintendo", "Baguette", "Hanky", "Mask"],
    key="selection",
)
submitted = form.form_submit_button("Submit", on_click=callback)

st.session_state["REGION_OF_INTEREST"]
st.session_state["counter"]

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.