En la jerga del desarrollo de interfaces de usuario se lo conoce como Combobox, pues se trata de una combinación entre una lista y una caja de texto. Así, puede actuar como una lista desplegable con determinadas opciones y, opcionalmente, permitir al usuario escribir un valor que no se encuentre en la lista.
Fue introducido en Tk 8.5 y se provee a través de la clase ttk.Combobox
, la cual hereda de ttk.Entry
, por lo que todas las operaciones aplicables a una caja de texto también aplican para un combobox.
El siguiente código crea una simple ventana con una lista desplegable vacía.
#!/usr/bin/env python # -*- coding: utf-8 -*- from tkinter import ttk import tkinter as tk class Application(ttk.Frame): def __init__(self, main_window): super().__init__(main_window) main_window.title("Combobox") self.combo = ttk.Combobox(self) self.combo.place(x=50, y=50) main_window.configure(width=300, height=200) self.place(width=300, height=200) main_window = tk.Tk() app = Application(main_window) app.mainloop()
Para evitar que el usuario ingrese sus propios valores, es decir, que el control se comporte únicamente como una lista desplegable y no como una caja de texto, utilizamos:
self.combo = ttk.Combobox(self, state="readonly")
Para añadir un conjunto de opciones, asignamos una lista a la propiedad values
.
self.combo["values"] = ["Python", "C", "C++", "Java"]
Un combobox en Tk trabaja únicamente con cadenas. Cualquier otro tipo de objeto será convertido antes de ser añadido a la lista.
La función Combobox.get
retorna la opción seleccionada o bien escrita manualmente por el usuario (no hay distinción en ese sentido).
value = self.combo.get()
Siempre retorna una cadena y, en caso de no haber ninguna selección, devuelve una cadena vacía.
También es posible obtener el índice (es decir, su posición en la lista comenzando desde el 0) del elemento seleccionado vía Combobox.current()
.
index = self.combo.current()
Si no hay ningún elemento seleccionado o bien no se encuentra entre las opciones provistas (ha sido ingresado por el usuario) el valor de retorno es -1
.
Análogamente, Combobox.set()
establece el contenido de la lista.
self.combo.set("Python")
Y para seleccionar un elemento según su posición:
# Selecciona "C++". self.combo.current(2)
Para obtener todas las opciones de la lista:
# Retorna ('Python', 'C', 'C++', 'Java') values = self.combo["values"]
Nótese que retorna una tupla, no una lista. Para añadir una opción sin reemplazar a las demás, utilícese:
values = list(self.combo["values"]) self.combo["values"] = values + ["Nuevo elemento"]
Para remover todas las opciones, simplemente:
# Vaciar lista. self.combo["values"] = []
ttk.Combobox
introduce un nuevo evento llamado <<ComboboxSelected>>
que es enviado cuando cambia la opción seleccionada.
def __init__(self, main_window): super().__init__(main_window) main_window.title("Combobox") self.combo = ttk.Combobox(self) self.combo.place(x=50, y=50) self.combo["values"] = ["Python", "C", "C++", "Java"] self.combo.bind("<<ComboboxSelected>>", self.selection_changed) main_window.configure(width=300, height=200) self.place(width=300, height=200) def selection_changed(self, event): print("Nuevo elemento seleccionado:", self.combo.get())
Nótese que este evento no registra cambios introducidos manualmente por el usuario.
Para saber cuándo se ha abierto la lista (esto es, presionado en la flecha en el extremo derecho), en lugar de un evento simplemente se pasa una función al parámetro postcommand
.
def __init__(self, main_window): # ... self.combo = ttk.Combobox(self, postcommand=self.dropdown_opened) # ... def dropdown_opened(self): print("Lista desplegada.")
Ignacio says:
como puedo generar dentro de un combobox , una muestra de diferentes elementos ( en mi caso son departamentos ) y que se abran sus datos desde la base de datos con sus caracteristicas, y que cada vez q seleccione uno en el combobox , estos se actualizen . Me esta costando asociar el combobox con la base de datos y a su vez generar una seleccion automatica de estos . Gracias!
Recursos Python says:
Hola, pasá por el foro y lo vemos. Saludos
pruebas says:
Arriba te explica una opción de como podrías hacerlo, con el evento ComboboxSelected…
Jefrson says:
Hola gracias por el tutorial
quisiera saber como puedo mostrar un texto en el combo que diga «Seleccione una opción» sin que este texto sea obtenido a la hora de validar
Recursos Python says:
¡Hola! Podés usar, después de crear la lista desplegable:
self.combo.set("Seleccione una opción")
Saludos
Javier says:
Una pregunta, si quiero que en funcion de lo seleccionado en mi lista se me ejecute una funcion u otra, como debo vincularla? Llevo tiempo intentandolo y no le doy resultado. Gracias!
Recursos Python says:
Hola. Vinculando el evento
<<ComboboxSelected>>
tal como se muestra al final del artículo.Saludos
Antonio ochoa says:
Hola tengo una duda como le hago para que mi funcion me retorne el valor de la lista selecionada sin usar boton y llamar la funcion. La idea es usando ComboboxSelected
Recursos Python says:
Hola Antonio. El anteúltimo retazo de código muestra exactamente eso. Saludos!
Sebastian says:
Hola! Muy bueno el tutorial. Te hago una consulta? Yo tengo un textbox que elije una linea de colectivo. En base a la linea de colectivo que se eligió, tengo que colocar en el combobox los ramales. Tenés idea como detectar el momento en que el cursor deja de estar en el textbox (es decir, cuando se termino de escribir allí), y pasa a estar en el combobox? En ese momento deberia consultar a la bd para completar con los valores correspondientes el combobos.
Recursos Python says:
Hola Sebastián, me alegro que te haya servido. Tenés que conectar el evento
<FocusIn>
de tu caja de texto vía el métodobind()
para saber cuándo recibe el foco y poder realizar la consulta. Si tenés problemas para implementar el código creá un nuevo tema en el foro.Saludos
Yuliana says:
Muy buena información.
Solo tengo una duda, si quiero llenar mi lista con información de mi base de datos con un select para mi
lista desplegables que opción o función debo utilizar.
De antemano, gracias!
Recursos Python says:
Sería algo así:
cursor.execute("SELECT ...")
combo["values"] = [row[0] for row in cursor.fetchall()]
Saludos!
Ronal says:
buenas, quisiera hacer un combobox y que cada item tenga un fondo de diferente color. buen tutorial, gracias por compartir
Brit says:
Buenos días!!
Muchas gracias por este tutorial, me ha servido de gran ayuda!!! Pero una cosina, si quiero que la lista se actualice según voy escribiendo, sabes que herramienta debo usar???
AYUDAIME PLEASEE
Un saludo.
Recursos Python says:
Hola, me alegro que te haya servido. La lista desplegable hereda la funcionalidad de la caja de texto, por lo que puedes asignarle una variable (
tk.StringVar
) vía el parámetrotextvariable
y luego determinar cuándo es modificada a través del métodotrace("w", callback)
.Te dejo un ejemplo aquí: https://pastebin.com/YqFxnpJy.
Saludos
Jaime Arias says:
Muchas gracias por este tutorial !
Jorge Luis Silva Ojeda says:
Muy buena información.
Solo tengo una duda, si quiero poner 2 listas desplegables, pero que la 2da lista dé resultados diferentes dependiendo de la opción que se dio en la 1ra, (algo así como escoger el país y que en la siguiente te dé una lista de los estados) ¿qué debería agregar?
De antemano, gracias!
Recursos Python says:
Hola. En ese caso deberías asociar el evento
<<ComboboxSelected>>
de la primera lista para que al seleccionar una opción se carguen los elementos de la segunda.Saludos