I want to make multiple checkboxes in streamlit like in this image below.
But I want the behavior, that just on checkbox can be selected. That means, if a checkbox is selected and you select another one that cancels out the first selection.
I also tried it out with st.radio, but the problem there is that I can't have no selection and it doesn't fulfill my use case.
The simplest could be to use st.radio
with another radio Show All
or Show Nothing
With st.checkbox
you could use on_change
to run code which set False
on other checkboxes.
Every checkbox needs unique key
, and it has to send this key to on_check
.
It also need to keep all keys on list - to use it late to uncheck all other checkboxes
Minimal working code:
import streamlit as st
def on_change_checkbox(current_key):
#print('current_key:', current_key)
# uncheck all checkboxes except current
for key in checkbox_keys:
if key != current_key:
st.session_state[key] = False
checkbox_keys = []
key = 'cb pdf'
st.checkbox('Select PDF', key=key, on_change=on_change_checkbox, args=(key,))
checkbox_keys.append(key)
key = 'cb database'
st.checkbox('Select Database', key=key, on_change=on_change_checkbox, args=(key,))
checkbox_keys.append(key)
key = 'cb something else'
st.checkbox('Select Something Else', key=key, on_change=on_change_checkbox, args=(key,))
checkbox_keys.append(key)
Example which use dictionary with lists to group checkboxes
#!/usr/bin/env python3
"""
# author: Bartlomiej "furas" Burek (https://blog.furas.pl)
# date: 2024.06.20
# [python - Streamlit multiple Checkboxes with one allowed Selection - Stack Overflow](https://stackoverflow.com/questions/78647325/streamlit-multiple-checkboxes-with-one-allowed-selection/78648360#78648360)
"""
import streamlit as st
def on_change_checkbox(current_key, group):
print('current_key:', current_key, group)
# uncheck all checkboxes except current
for key in checkbox_keys[group]:
if key != current_key:
st.session_state[key] = False
checkbox_keys = {}
# ----
st.text('Source')
checkbox_keys['Source'] = []
key = 'cb source pdf'
st.checkbox('Select PDF', key=key, on_change=on_change_checkbox, args=(key, 'Source'))
checkbox_keys['Source'].append(key)
key = 'cb source database'
st.checkbox('Select Database', key=key, on_change=on_change_checkbox, args=(key, 'Source'))
checkbox_keys['Source'].append(key)
key = 'cb source something else'
st.checkbox('Select Something Else', key=key, on_change=on_change_checkbox, args=(key, 'Source'))
checkbox_keys['Source'].append(key)
# ----
st.text('Target')
checkbox_keys['Target'] = []
key = 'cb target pdf'
st.checkbox('Select PDF', key=key, on_change=on_change_checkbox, args=(key, 'Target'))
checkbox_keys['Target'].append(key)
key = 'cb target database'
st.checkbox('Select Database', key=key, on_change=on_change_checkbox, args=(key, 'Target'))
checkbox_keys['Target'].append(key)
key = 'cb target something else'
st.checkbox('Select Something Else', key=key, on_change=on_change_checkbox, args=(key, 'Target'))
checkbox_keys['Target'].append(key)
With st.radio
you may only add button which assigns None
and this will clear selection.
import streamlit as st
def clear_radio(current_key):
#print('current_key:', current_key)
# uncheck radio
st.session_state[current_key] = None
key = 'r select'
st.radio('Select:', key=key, index=None, options=['Select PDF', 'Select Database', 'Select Something Else'])
st.button('Clear', on_click=clear_radio, args=(key,))