8

Hi all I am building a simple web app with streamlit in python. I need to add 3 buttons but they must be on the same line.

Obviously the following code puts them on three different lines

st.button('Button 1')
st.button('Button 2')
st.button('Button 3')

Do you have any tips?

Wing
  • 642
  • 2
  • 5
  • 16
  • You can accept my answer or you can build your own Streamlit component with JS. https://streamlit.io/components Please remember this is a framework for data-science, not for front-end pixel perfection as Flask could be for example. – Joao Victor May 23 '22 at 22:00

3 Answers3

14

Apparently this should do it

col1, col2, col3 = st.columns([1,1,1])

with col1:
    st.button('1')
with col2:
    st.button('2')
with col3:
    st.button('3')
Wing
  • 642
  • 2
  • 5
  • 16
  • To get the buttons to be closer together, experiment with `columns = st.columns([1, 1, 1, 1, 1])` (or some other number of 1s) and then doing `with columns[0]` etc. – codeananda Jul 12 '23 at 16:12
3

I had a similar problem - to add an action button to a table. I came to the following approach:

import streamlit as st

        # # Show users table 
        colms = st.columns((1, 2, 2, 1, 1))
        fields = ["№", 'email', 'uid', 'verified', "action"]
        for col, field_name in zip(colms, fields):
            # header
            col.write(field_name)

        for x, email in enumerate(user_table['email']):
            col1, col2, col3, col4, col5 = st.columns((1, 2, 2, 1, 1))
            col1.write(x)  # index
            col2.write(user_table['email'][x])  # email
            col3.write(user_table['uid'][x])  # unique ID
            col4.write(user_table['verified'][x])   # email status
            disable_status = user_table['disabled'][x]  # flexible type of button
            button_type = "Unblock" if disable_status else "Block"
            button_phold = col5.empty()  # create a placeholder
            do_action = button_phold.button(button_type, key=x)
            if do_action:
                 pass # do some action with row's data
                 button_phold.empty()  #  remove button

And it works fine. The object — user_table — is a dictionary very similar to DataFrame, where each key — is a column (i.e. list in pythonic terms). And here how it looks like (Note “Blocked” — that is the result of action): enter image description here

0

Generalizing this answer a bit to use a dynamic number of buttons:

import streamlit as st  # 1.18.1


button_text = "foo", "bar", "baz"

for text, col in zip(button_text, st.columns(len(button_text))):
    if col.button(text):
        col.write(f"{text} clicked")

If the text isn't necessarily unique:

button_text = "foo", "bar", "foo"
pairs = zip(button_text, st.columns(len(button_text)))

for i, (text, col) in enumerate(pairs):
    if col.button(text, key=f"{text}-{i}"):
        col.write(f"{text}-{i} clicked")
ggorlen
  • 44,755
  • 7
  • 76
  • 106