Más allá de lo básico: Guía completa de los botones de Streamlit
Updated on
Streamlit facilita convertir scripts de Python en aplicaciones interactivas, y los botones suelen ser la primera interacción que esperan las personas usuarias. El widget st.button
puede verse minimalista, pero desbloquea flujos que van desde simples cambios hasta acciones de varios pasos. Esta guía renovada resume la API moderna, aclara malentendidos comunes y ofrece patrones comprobados para crear experiencias fiables basadas en botones.
¿Buscas un componente de analítica visual listo para usar en tus proyectos de Streamlit?
PyGWalker (opens in a new tab) incorpora una interfaz de exploración parecida a Tableau directamente en tus apps de Streamlit. Mira cómo explorar datos con PyGWalker (opens in a new tab) para verlo en acción o lee la guía de integración.
Entender st.button
Inicio rápido
En esencia, st.button
renderiza un elemento clicable y devuelve True
durante la ejecución del script justo después de un clic. Ese booleano suele bastar para flujos sencillos:
import streamlit as st
if st.button("Saludar"):
st.write("¡Hola, Streamlit!")
Streamlit vuelve a ejecutar todo el script cada vez que un widget cambia. Por ese modelo de reinicio, asegúrate de que el trabajo dentro del bloque if
sea idempotente o esté protegido con estado adicional.
Argumentos clave que debes conocer
st.button
acepta varios argumentos opcionales que cubren la mayoría de necesidades de personalización:
key
: Identificador único cuando tienes varios botones con la misma etiqueta.help
: Texto de ayuda que se muestra al pasar el cursor.on_click
: Callback que se ejecuta cuando se presiona el botón.args
/kwargs
: Argumentos posicionales y con nombre que se envían al callback.type
: Elige entre los estilos"primary"
y"secondary"
para mantener la coherencia con el tema de Streamlit.disabled
: Impide que las personas interactúen con el botón.use_container_width
: Estira el botón al ancho del contenedor padre.
def refresh_data(verbose: bool = False, limit: int | None = None) -> None:
st.session_state["last_result"] = load_data(limit=limit)
if verbose:
st.success("Datos actualizados")
st.button(
"Actualizar datos",
key="refresh",
help="Obtén los registros más recientes de la API",
type="primary",
use_container_width=True,
on_click=refresh_data,
args=(True,),
kwargs={"limit": 500},
)
Gestionar interacciones más allá del valor devuelto
Uso de callbacks y del estado de sesión
Los callbacks se ejecutan después de que Streamlit recopile los cambios de los widgets, por lo que son ideales para encapsular lógica y actualizar st.session_state
:
import datetime as dt
import streamlit as st
if "last_clicked" not in st.session_state:
st.session_state.last_clicked = None
def mark_timestamp() -> None:
st.session_state.last_clicked = dt.datetime.now(dt.timezone.utc)
st.button("Registrar marca de tiempo", on_click=mark_timestamp, type="primary")
st.write("Último clic:", st.session_state.last_clicked or "Aún no")
Los callbacks mantienen el script principal declarativo, evitan un anidamiento profundo de if
y conservan el estado entre reinicios.
Crear comportamiento de tipo interruptor
Los botones no permanecen presionados, pero puedes combinarlos con el estado de sesión para lograr interacciones tipo toggle:
import streamlit as st
st.session_state.setdefault("show_advanced", False)
if st.button("Mostrar u ocultar opciones avanzadas"):
st.session_state.show_advanced = not st.session_state.show_advanced
if st.session_state.show_advanced:
st.info("La configuración avanzada aparece aquí.")
Para controles persistentes (por ejemplo, encendido/apagado) considera widgets como st.checkbox
o st.toggle
, que comunican mejor el estado.
Técnicas de maquetación para botones
Streamlit organiza los elementos en el orden en que aparecen, pero sigues teniendo control del diseño mediante contenedores:
col1, col2 = st.columns(2)
with col1:
st.button("Anterior", key="prev", type="secondary")
with col2:
st.button("Siguiente", key="next", type="primary", use_container_width=True)
with st.sidebar:
st.button("Restablecer filtros", key="reset")
Usa st.container()
o st.expander()
para agrupar acciones relacionadas y st.columns()
para alinear botones en la misma fila sin depender de HTML crudo.
Opciones de estilo y sobreescrituras con CSS
Streamlit limita intencionalmente la personalización directa para mantener la coherencia, pero aún tienes alternativas:
- Prefiere el preset integrado
type="primary"
para destacar yuse_container_width=True
para diseños responsivos. - Ajusta los colores predeterminados mediante la configuración global del tema (
.streamlit/config.toml
). - Para estilos personalizados, inyecta CSS acotado con
st.markdown(..., unsafe_allow_html=True)
.
import streamlit as st
st.markdown(
"""
<style>
.custom-button button {
background: linear-gradient(135deg, #005bbb, #00bcd4);
color: white;
border: 0;
padding: 0.6rem 1.5rem;
border-radius: 999px;
transition: transform 0.1s ease-in-out;
}
.custom-button button:hover {
transform: translateY(-1px);
}
</style>
""",
unsafe_allow_html=True,
)
with st.container():
st.markdown('<div class="custom-button">', unsafe_allow_html=True)
st.button("Botón degradado", key="custom")
st.markdown("</div>", unsafe_allow_html=True)
Mantén las sobreescrituras de CSS enfocadas; grandes bloques en línea son difíciles de mantener y pueden romperse si Streamlit cambia nombres internos de clases.
Patrones prácticos
- Revelado progresivo: combina un botón con
st.session_state
para mostrar entradas o texto adicional solo cuando sea necesario. - Pasos de procesamiento de datos: desactiva botones (
disabled=True
) hasta que existan requisitos previos como cargas de archivos o tokens de autenticación. - Flujos de descarga: usa
st.download_button
cuando necesites entregar archivos; reservast.button
para lógica dentro de la app.
Conclusión
Los botones sustentan muchos recorridos de usuario en Streamlit. Al combinar el valor booleano devuelto, la API de callbacks y st.session_state
, puedes coordinar comportamientos complejos sin abandonar el paradigma reactivo. Apóyate en los primitivos de maquetación para la alineación, recurre al CSS solo cuando sea necesario y considera otros widgets cuando sea más claro mostrar un estado persistente. Un diseño cuidadoso de los botones mantiene tus apps de Streamlit rápidas, intuitivas y confiables.
Preguntas frecuentes
¿Cómo se crea un botón en Streamlit?
Usa st.button("Etiqueta")
. La función devuelve True
en la ejecución activada por el clic, así que coloca tu lógica en el bloque if
correspondiente o pasa un callback con on_click
.
¿Cómo se posiciona un botón en Streamlit?
Envuelve los widgets en primitivos de diseño como st.columns
, st.container
, st.sidebar
o st.expander
. Estos contenedores controlan la posición sin recurrir a HTML puro.
¿Cómo se crea un botón de opción en Streamlit?
Utiliza st.radio(label, options)
para presentar opciones mutuamente excluyentes. La selección se devuelve de inmediato y puede guardarse en st.session_state
para lógica posterior.
¿Cuáles son las desventajas de Streamlit?
El modelo de reinicio de scripts de Streamlit simplifica el desarrollo, pero puede resultar limitado cuando necesitas control granular del diseño, tareas en segundo plano prolongadas o personalización de estilos profunda. Aun así, el ecosistema evoluciona rápidamente: nuevos widgets, opciones de temas y utilidades de estado de sesión reducen cada vez más esas brechas.