229 votes

Comment passer des arguments à une commande Button dans Tkinter ?

Supposons que j'ai les Button créés avec Tkinter en Python :

 import Tkinter as Tk
win = Tk.Toplevel()
frame = Tk.Frame(master=win).grid(row=1, column=1)
button = Tk.Button(master=frame, text='press', command=action)

La méthode action est appelée lorsque j'appuie sur le bouton, mais si je voulais passer des arguments à la méthode action ?

J'ai essayé avec le code suivant :

 button = Tk.Button(master=frame, text='press', command=action(someNumber))

Cela invoque simplement la méthode immédiatement et appuyer sur le bouton ne fait rien.

342voto

Voo Points 11981

Personnellement, je préfère utiliser lambdas dans un tel scénario, car imo c'est plus clair et plus simple et ne vous oblige pas non plus à écrire beaucoup de méthodes wrapper si vous n'avez pas le contrôle sur la méthode appelée, mais c'est certainement une question de goût.

C'est comme ça que vous le feriez avec un lambda (notez qu'il existe également une implémentation du curry dans le module fonctionnel, vous pouvez donc l'utiliser aussi):

 button = Tk.Button(master=frame, text='press', command= lambda: action(someNumber))

139voto

Dologan Points 541

Cela peut également être fait en utilisant partial partir de la bibliothèque standard functools , comme ceci :

 from functools import partial
#(...)
action_with_arg = partial(action, arg)
button = Tk.Button(master=frame, text='press', command=action_with_arg)

11voto

user2188314 Points 11

La capacité de Python à fournir des valeurs par défaut pour les arguments de fonction nous donne une issue.

 def fce(x=myX, y=myY):
    myFunction(x,y)
button = Tk.Button(mainWin, text='press', command=fce)

Voir : http://infohost.nmt.edu/tcc/help/pubs/tkinter/web/extra-args.html

Pour plus de boutons, vous pouvez créer une fonction qui renvoie une fonction :

 def fce(myX, myY):
    def wrapper(x=myX, y=myY):
        pass
        pass
        pass
        return x+y
    return wrapper

button1 = Tk.Button(mainWin, text='press 1', command=fce(1,2))
button2 = Tk.Button(mainWin, text='press 2', command=fce(3,4))
button3 = Tk.Button(mainWin, text='press 3', command=fce(9,8))

5voto

Christoph Frings Points 270

S'appuyant sur la réponse de Matt Thompsons : une classe peut être rendue appelable afin qu'elle puisse être utilisée à la place d'une fonction :

 import tkinter as tk

class Callback:
    def __init__(self, func, *args, **kwargs):
        self.func = func
        self.args = args
        self.kwargs = kwargs
    def __call__(self):
        self.func(*self.args, **self.kwargs)

def default_callback(t):
    print("Button '{}' pressed.".format(t))

root = tk.Tk()

buttons = ["A", "B", "C"]

for i, b in enumerate(buttons):
    tk.Button(root, text=b, command=Callback(default_callback, b)).grid(row=i, column=0)

tk.mainloop()

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X