GUI de ejemplo:
Digamos que tengo la GUI:
import tkinter as tk
root = tk.Tk()
btn = tk.Button(root, text="Press")
btn.pack()
root.mainloop()
¿Qué sucede cuando se presiona un botón?
Observe que cuando btnse presiona llama a su propia función, que es muy similar a button_press_handlela del siguiente ejemplo:
def button_press_handle(callback=None):
if callback:
callback() # Where exactly the method assigned to btn['command'] is being callled
con:
button_press_handle(btn['command'])
Simplemente puede pensar que esa commandopción debe establecerse como, la referencia al método que queremos llamar, similar a callbackin button_press_handle.
Llamar a un método ( devolución de llamada ) cuando se presiona el botón
Sin argumentos
Entonces, si quería printalgo cuando se presiona el botón, necesitaría configurar:
btn['command'] = print # default to print is new line
Preste mucha atención a la falta de ()un printmétodo que se omite en el sentido de que: "Este es el nombre del método al que quiero que llame cuando lo presione, pero no lo llame en este mismo instante". Sin embargo, no pasé ningún argumento para el, printpor lo que imprimió lo que imprime cuando se lo llamó sin argumentos.
Con argumento (s)
Ahora, si también quisiera pasar argumentos al método que quiero que me llamen cuando se presiona el botón, podría hacer uso de las funciones anónimas, que se pueden crear con la declaración lambda , en este caso para el printmétodo incorporado, como el siguiente :
btn['command'] = lambda arg1="Hello", arg2=" ", arg3="World!" : print(arg1 + arg2 + arg3)
Llamar a varios métodos cuando se presiona el botón
Sin argumentos
También puede lograrlo usando la lambdadeclaración, pero se considera una mala práctica y, por lo tanto, no la incluiré aquí. La buena práctica es definir un método separado multiple_methodsque llame a los métodos deseados y luego configurarlo como la devolución de llamada al presionar el botón:
def multiple_methods():
print("Vicariously") # the first inner callback
print("I") # another inner callback
Con argumento (s)
Para pasar argumentos al método que llama a otros métodos, nuevamente use la lambdadeclaración, pero primero:
def multiple_methods(*args, **kwargs):
print(args[0]) # the first inner callback
print(kwargs['opt1']) # another inner callback
y luego establecer:
btn['command'] = lambda arg="live", kw="as the" : a_new_method(arg, opt1=kw)
Devolver objeto (s) de la devolución de llamada
También tenga en cuenta que callbackno puede realmente returnporque solo se llama dentro button_press_handlecon callback()en lugar de return callback(). Lo hace, returnpero no en cualquier lugar fuera de esa función. Por lo tanto, debería modificar los objetos a los que se puede acceder en el ámbito actual.
Ejemplo completo con modificaciones de objeto globales
El siguiente ejemplo llamará a un método que cambia btnel texto de cada vez que se presiona el botón:
import tkinter as tk
i = 0
def text_mod():
global i, btn # btn can be omitted but not sure if should be
txt = ("Vicariously", "I", "live", "as", "the", "whole", "world", "dies")
btn['text'] = txt[i] # the global object that is modified
i = (i + 1) % len(txt) # another global object that gets modified
root = tk.Tk()
btn = tk.Button(root, text="My Button")
btn['command'] = text_mod
btn.pack(fill='both', expand=True)
root.mainloop()
Espejo