0

I used the information found in this post to create several buttons in Streamlit: HOW TO STYLE A BUTTON IN STREAMLIT. The result is the following: enter image description here The code thai I used is:

def style_button(click_button_i, nb_buttons):
    def get_button_indices(button_i):
        return {
            'nth_child': button_i,
            'nth_last_child': nb_buttons - button_i + 1
        }

    click_style = """
    div[data-testid*="stHorizontalBlock"] > div:nth-child(%(nth_child)s):nth-last-child(%(nth_last_child)s) button {
        border-color: rgb(50,205,50);
        color: rgb(50,205,50);

        box-shadow: rgba(50,205,50, 0.5) 0px 0px 0px 0.2rem;
        outline: currentcolor none medium;
    }
    """
    unclick_style = """
    div[data-testid*="stHorizontalBlock"] > div:nth-child(%(nth_child)s):nth-last-child(%(nth_last_child)s) button {
        pointer-events: none;
        cursor: not-allowed;
        opacity: 0.65;
        filter: alpha(opacity=65);
        -webkit-box-shadow: none;
        box-shadow: none;
    }
    """
    style = ""
    for i in range(nb_buttons):
        i += 1
        if i == click_button_i:
            style += click_style % get_button_indices(i)
        else:
            style += unclick_style % get_button_indices(i)
    st.markdown(f"<style>{style}</style>", unsafe_allow_html=True)

and:

st.subheader("This is the corect answer ?")
col1, col2= st.columns([1,1])
with col1:
    st.button("YES", on_click=style_button, key= "a",kwargs={
        'click_button_i': 1, 'nb_buttons': 2
    })
with col2:
    st.button("NO", on_click=style_button, key="b",kwargs={
        'click_button_i': 2, 'nb_buttons': 2
    })

st.subheader("Some other stuf here...")

st.subheader("Is this a corect answer?")
col1, col2= st.columns([1,1])
with col1:
    st.button("YES", on_click=style_button, key= "c",kwargs={
        'click_button_i': 1, 'nb_buttons': 2
    })
with col2:
    st.button("NO", on_click=style_button, key="d",kwargs={
        'click_button_i': 2, 'nb_buttons': 2
    })

As you can see, when you click on a button (for example YES), the other YES buttons are automatically selected and remain green, without having clicked on any of them.

My question is: is it possible to create several rows of buttons, each row independent of the other?

I tried to change the number of buttons in st.button, I tried to define a style_button2, but it seems that the beacon for st.buttons is always the same: data-testid* and once the style button function is applied it remains the same for all beacons of the same type . I tried to give another name to the beacon, for example div data_testid1, but it doesn't change. Maybe these options are ridiculous, but not knowing much about CSS, I don't quite understand how the nth_child thing works, probably some changes are needed there, but I don't know how.

Thanks for the reply!

ferdy
  • 4,396
  • 2
  • 4
  • 16

1 Answers1

0

as someone new in streamlit, I would like to try to help. Firstly u can use normal css button changes as seen here.

import streamlit as st

click_style = """ 
<style> 
div[data-testid*="stButton"] > button:active {
    border-color: rgb(50,205,50);
    color: rgb(50,205,50);
    box-shadow: rgba(50,205,50, 0.5) 0px 0px 0px 0.2rem;
    outline: currentcolor none medium;
}
div[data-testid*="stButton"] > button{
    pointer-events: none;
    cursor: not-allowed;
    opacity: 0.65;
    filter: alpha(opacity=65);
    -webkit-box-shadow: none;
    box-shadow: none;
}
div[data-testid*="stButton"] > button:visited{
    pointer-events: none;
    cursor: not-allowed;
    opacity: 0.65;
    filter: alpha(opacity=65);
    -webkit-box-shadow: none;
    box-shadow: none;
}
</style>

"""

Secondly you do not need to use different arguments to identify buttons, every button has a unique key(even if you do not identify them but you did) so use can access these keys to identify a spesific button by st.session_state.key. So in this case I did not use them but if you want we can add them :D. The remaining code turn out to be

st.markdown(click_style, unsafe_allow_html=True)


st.subheader("This is the corect answer ?")
col1, col2 = st.columns([1, 1])
with col1:
    st.button("YES", key="a")
with col2:
    st.button("NO", key="b")

st.subheader("Some other stuf here...")

st.subheader("Is this a corect answer?")
col1, col2 = st.columns([1, 1])
with col1:
    st.button("YES", key="c")
with col2:
    st.button("NO", key="d")

if anything is unclear I could try to explain.

sarbend
  • 16
  • 3