How to handle multiple widgets error with simple way?

I want to build a widget with a specific key.
And the widget may be added or removed by other condition.
If it is removed, I would like to build a new one with same key. (so uuid way is not suitable for this case)

What I want is like below, but it is not work.
DuplicateWidgetID : There are multiple widgets with the same key='aaa' .

import streamlit as st

st.selectbox('aaa',[1,2,3], key='aaa')

del st.session_state['aaa']

st.selectbox('aaa',[1,2,3], key='aaa')

I also tried st.empty() but still failed.

Is there any simple way to do this?


Hi @gavin811201. According to my understanding you need to stop the rerunning of the application. Because streamlit follows every time rerun the whole application from top to bottom

1 Like

Read the streamlit main concept especially the data flow.

I have read the document but can’t find the solution.

So using same label and key to create widget is impossible even if I delete the key in st.session_state, right?

Same key is not allowed. Same label is allowed.

Here is an approach to reusing a key. We monitor the usage of a key, if it is not yet used, we can create a widget using that key. However if it is already used, we need to decrement the usage counter so that we can use it again. This is triggered by a button in my example code.

import streamlit as st
from streamlit import session_state as ss
import random

# Maintain a variable to keep track of widget key usage.
# If the usage of the key is zero, we can use it.
if 'key_monitor' not in ss:
    ss.key_monitor = {'aaa_key': 0, 'bbb_key': 0}

# Create a variable for label.
if 'label' not in ss:
    ss.label = 'label 0'

def change():
    ss.key_monitor['aaa_key'] = 0  # reset to recreate

def create():
    if ss.key_monitor['aaa_key'] > 0:
        ss.label = 'label ' + str(random.randint(10, 99))
        ss.key_monitor['aaa_key'] -= 1  # decrement to create a new widget/label

# Create a widget with aaa_key if it not used yet.
if ss.key_monitor['aaa_key'] == 0:
    ss.key_monitor['aaa_key'] += 1
    st.selectbox(ss.label, [1,2,3], key='aaa_key', on_change=change)

# Create a new widget using the aaa_key.
st.button('Create a new widget using existing key', on_click=create)