samedi 19 avril 2014

python - appel d'une méthode avec un gestionnaire d'événement - Stack Overflow


Why, if I put a "normal" call to the method button1Click() in the bind call, does my program not even start? By removing the parenthesis the problem is solved. I'm using this program as reference: Thinking in Tkinter


Also, why should I add the event argument to my button1Click() method?


from Tkinter import *
class MyApp:
def __init__(self, parent):
self.myParent = parent
self.myContainer1 = Frame(parent)
self.myContainer1.pack()

self.button1 = Button(self.myContainer1)
self.button1.configure(text="OK", background= "green")
self.button1.pack(side=LEFT)
self.button1.bind("<Button-1>", self.button1Click) # <--- no () !

def button1Click(self, event):
self.button2 = Button(self.myContainer1, text="lol")
self.button2.bind("<Button-1>", self.button1Click)
self.button2.pack()

root = Tk()
myapp = MyApp(root)
root.mainloop()



bind() expects something that is callable and that expects an argument.


If you pass self.button1Click(), you effectively pass it None, because that is what is returned by this call.


As the call is to be performed by the clickable object, you are not supposed to call it yourself.


So, next step: You pass it self.button1Click, and you clock the button. Then the given "thing" is tried to be called with an event object as argument, but that fails, because the method is not prepared for that.


So you have 2 options:



  • Either you modify the method so it can be called with an event object, such as def button1Click(self, event):,

  • or you wrap it in a lambda call: lambda event: self.button1Click().


In the latter case, you give the bind() method a callable which accepts exactly one argument, and does the call as wanted at the time of calling (thus the ()).




You can call the method button1Click "normally" using lambda. What might be happening right now is that it would be getting called anyhow.


For ex: command=lambda:self.button1Click()


You can pass more arguments if you like by putting them in the parenthesis.


You need to use the event argument because whenever you bind a method you are passing event object too automatically. In your case,its two arguments-the event object & self.



Why, if I put a "normal" call to the method button1Click() in the bind call, does my program not even start? By removing the parenthesis the problem is solved. I'm using this program as reference: Thinking in Tkinter


Also, why should I add the event argument to my button1Click() method?


from Tkinter import *
class MyApp:
def __init__(self, parent):
self.myParent = parent
self.myContainer1 = Frame(parent)
self.myContainer1.pack()

self.button1 = Button(self.myContainer1)
self.button1.configure(text="OK", background= "green")
self.button1.pack(side=LEFT)
self.button1.bind("<Button-1>", self.button1Click) # <--- no () !

def button1Click(self, event):
self.button2 = Button(self.myContainer1, text="lol")
self.button2.bind("<Button-1>", self.button1Click)
self.button2.pack()

root = Tk()
myapp = MyApp(root)
root.mainloop()


bind() expects something that is callable and that expects an argument.


If you pass self.button1Click(), you effectively pass it None, because that is what is returned by this call.


As the call is to be performed by the clickable object, you are not supposed to call it yourself.


So, next step: You pass it self.button1Click, and you clock the button. Then the given "thing" is tried to be called with an event object as argument, but that fails, because the method is not prepared for that.


So you have 2 options:



  • Either you modify the method so it can be called with an event object, such as def button1Click(self, event):,

  • or you wrap it in a lambda call: lambda event: self.button1Click().


In the latter case, you give the bind() method a callable which accepts exactly one argument, and does the call as wanted at the time of calling (thus the ()).



You can call the method button1Click "normally" using lambda. What might be happening right now is that it would be getting called anyhow.


For ex: command=lambda:self.button1Click()


You can pass more arguments if you like by putting them in the parenthesis.


You need to use the event argument because whenever you bind a method you are passing event object too automatically. In your case,its two arguments-the event object & self.


0 commentaires:

Enregistrer un commentaire