HOWTO · Tkinter
Cómo pasar argumentos al comando del botón Tkinter
Cómo pasar argumentos al comando del botón Tkinter
En esta página
La opción command de un botón de Tkinter espera un objeto invocable. Para pasarle argumentos, asígnalos de antemano y deja que Tkinter invoque ese objeto cuando se haga clic en el botón. Escribir command=show_message("Saved") llama a la función mientras se crea el botón; usa partial o una función envolvente con lambda para aplazar la llamada.
Pasar argumentos con functools.partial
Usa functools.partial cuando quieras vincular argumentos a una función existente. Devuelve un objeto invocable con esos valores asociados, por lo que puedes asignarlo directamente a la opción command de un botón. Esta simulación sin interfaz gráfica reproduce la opción command de un botón para que el comportamiento del callback pueda observarse sin abrir una ventana. Ejecuta este ejemplo:
from functools import partial
def show_message(message):
print(message)
class Button:
def __init__(self, command):
self.command = command
def click(self):
self.command()
save_button = Button(command=partial(show_message, "Saved"))
remove_button = Button(command=partial(show_message, "Removed"))
save_button.click()
remove_button.click()
Saved
Removed
Cada clic simulado invoca el objeto invocable almacenado e imprime el mensaje asociado. Para abrir una ventana real, ejecuta este script completo de Tkinter y haz clic en cualquiera de los botones; la etiqueta muestra el mensaje y la categoría correspondientes. El texto visible de los botones y de la etiqueta permanece en inglés, porque los bloques de código y de salida se conservan sin cambios:
from functools import partial
def show_message(message, category):
result.config(text=f"{message} ({category})")
try:
import tkinter as tk
except ImportError as error:
print(f"Tkinter is unavailable: {error}")
else:
try:
root = tk.Tk()
except tk.TclError as error:
print(f"A graphical display is required to open the Tkinter window: {error}")
else:
root.title("Button callbacks with partial")
result = tk.Label(root, text="Choose an action")
result.pack(padx=12, pady=8)
tk.Button(
root,
text="Save profile",
command=partial(show_message, "Saved", "profile"),
).pack(padx=12, pady=4)
tk.Button(
root,
text="Remove draft",
command=partial(show_message, "Removed", "draft"),
).pack(padx=12, pady=4)
root.mainloop()
El callback acepta tanto message como category, que son los dos valores asociados en cada llamada a partial. partial resulta útil cuando la función de destino ya tiene la firma adecuada y quieres vincular uno o más valores al asignarla a command.
Pasar argumentos con una función lambda
Una función lambda puede envolver una llamada y proporcionar sus argumentos cuando Tkinter la invoque. La expresión lambda: show_message("Saved") crea un objeto invocable sin argumentos; la llamada a la función que contiene se realiza después, al hacer clic. La sintaxis de una lambda con parámetros es lambda parameters: expression.
Esta simulación sin interfaz gráfica guarda cada lambda en una opción command similar a la de un botón y la invoca para simular un clic. Ejecuta este ejemplo:
def greet(name):
print(f"Hello, {name}!")
class Button:
def __init__(self, command):
self.command = command
def click(self):
self.command()
ada_button = Button(command=lambda: greet("Ada"))
sam_button = Button(command=lambda: greet("Sam"))
ada_button.click()
sam_button.click()
Hello, Ada!
Hello, Sam!
Cada clic simulado invoca la lambda guardada e imprime el saludo seleccionado. Para abrir una ventana real, ejecuta este script completo de Tkinter y haz clic en cualquiera de los botones; la etiqueta cambia para mostrar el saludo seleccionado:
def greet(name):
result.config(text=f"Hello, {name}!")
try:
import tkinter as tk
except ImportError as error:
print(f"Tkinter is unavailable: {error}")
else:
try:
root = tk.Tk()
except tk.TclError as error:
print(f"A graphical display is required to open the Tkinter window: {error}")
else:
root.title("Button callbacks with lambda")
result = tk.Label(root, text="Choose a greeting")
result.pack(padx=12, pady=8)
tk.Button(
root,
text="Greet Ada",
command=lambda: greet("Ada"),
).pack(padx=12, pady=4)
tk.Button(
root,
text="Greet Sam",
command=lambda: greet("Sam"),
).pack(padx=12, pady=4)
root.mainloop()
Elige partial cuando quieras vincular valores a una función existente y dejar visible esa vinculación en la asignación a command. Elige una lambda cuando la llamada requiera un pequeño ajuste en línea o cuando quieras expresar el callback junto al botón. Una lambda también puede pasar varios argumentos, como en lambda: show_message("Saved", "profile"); define la función de destino para que acepte esos valores. En ambos casos, asigna a command el objeto invocable en sí. Si añades paréntesis al callback al configurar el botón, la función se ejecuta de inmediato, antes de que alguien pueda hacer clic. Si el botón parece no hacer nada, comprueba que el nombre del callback esté bien escrito, que sus argumentos coincidan con la firma de la función y que el cuerpo de la función produzca un efecto observable, como imprimir algo o actualizar un widget.