Text not disappearing

Hi, I’m trying to make a program that will show different elements for different steps but for some reason during the “loop_function” step the text from the previous step (“process_steps”) is still visible but greyed out.

import streamlit as st
import time

# Step 1: File upload
st.title("File Processing App")

if "step" not in st.session_state:
    st.session_state.step = "waiting_for_file"
    st.session_state.data = []  # Placeholder for loop data
    st.session_state.checkboxes = []  # Store checkbox states

# Waiting for the file
if st.session_state.step == "waiting_for_file":
    uploaded_file = st.file_uploader("Upload your file", type=["txt", "csv"])
    if uploaded_file:
        st.session_state.step = "confirm_file"
        st.session_state.uploaded_file = uploaded_file

# Confirming file upload
if st.session_state.step == "confirm_file":
    st.write("File uploaded successfully.")
    if st.button("Start Processing"):
        st.session_state.step = "process_steps"
        st.rerun()

# Step 2: Processing steps
if st.session_state.step == "process_steps":
    st.write("Processing steps...")
    processing_steps = ["Step 1: Preprocessing", "Step 2: Analysis", "Step 3: Preparation"]

    for step in processing_steps:
        st.write(step)
        time.sleep(1)  # Mock processing time
    st.session_state.step = "loop_function"
    st.rerun()

# Step 3: Loop function
if st.session_state.step == "loop_function":
    st.write("Executing loop...")
    items = ["Item 1", "Item 2", "Item 3", "Item 4"]  # Mock data

    # Simulate processing each item
    for item in items:
        st.session_state.data.append(item)
        time.sleep(1)  # Mock processing time

    st.session_state.step = "display_checkboxes"
    st.rerun()

# Step 4: Display checkboxes
if st.session_state.step == "display_checkboxes":
    st.write("Review items:")
    for idx, item in enumerate(st.session_state.data):
        if len(st.session_state.checkboxes) <= idx:
            st.session_state.checkboxes.append(False)
        st.session_state.checkboxes[idx] = st.checkbox(item, value=st.session_state.checkboxes[idx])

    if st.button("Confirm Selection"):
        st.session_state.checked_count = sum(st.session_state.checkboxes)
        st.session_state.step = "summary"
        st.rerun()

# Step 5: Summary and next steps
if st.session_state.step == "summary":
    st.write(f"Number of selected items: {st.session_state.checked_count}")
    if st.button("Continue to Final Steps"):
        st.session_state.step = "final_steps"
        st.rerun()

if st.session_state.step == "final_steps":
    st.write("Executing final steps...")
    time.sleep(1)
    st.write("Processing complete!")

I’m also using st.rerun() to remove previous elements immediately. It works for other elements, is it the right way to do it? How do I properly hide/disable text or elements from the previous step?

Here’s a little explanation about stale elements.

A common solution is to use st.empty to forcibly clear out a page or section.

1 Like

Thanks! So I should wrap it with a container for every step, right?

# Step 2: Processing steps
if st.session_state.step == "process_steps":
    with st.container():
        st.write("Processing steps...")
        processing_steps = ["Step 1: Preprocessing", "Step 2: Analysis", "Step 3: Preparation"]

        for step in processing_steps:
            st.write(step)
            time.sleep(1)  # Mock processing time
        st.session_state.step = "loop_function"
        st.empty()
        st.rerun()

If everything has a container, you may still have the same problem (just happening inside the container instead of at the root).

Try this for exploration:

import streamlit as st
import time

def write_slow(x):
    for i in range(5):
        x
        time.sleep(.5)

def stage_container():
    parent = st.empty() # parent empty exists in all stages
    parent.empty() # transient empty exists just long enough to clear the screen
    time.sleep(.01)
    return parent.container() # actual container replaces transient empty

stage = st.radio("Stage", [1,2,3,4], horizontal=True)

if stage == 1:
    write_slow("one")
if stage == 2:
    write_slow("two")
if stage == 3:
    with stage_container():
        write_slow("three")
if stage == 4:
    with stage_container():
        write_slow("four")

If you switch between stages 1 and 2, you’ll see your current situation. If you switch between stages 3 and 4, you see how to use the empty to make sure things clear between stages. (The time.sleep(.01) is a workaround for a bug; when clearing and immediately replacing elements, the backend needs a little pause to make sure the frontend can keep up.)

Note: {1,2} → {3,4} will look especially bad since you’re going from five separate elements at the top level to just one. On the other hand, {3,4} → {1,2} works fine since you’re going from one element at the top level getting replaced by five.

1 Like

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