Lambda works weird with tkinter

I am trying to make a calculator using Tkinter. I tried to clear the code a bit, but fell into a trap. When creating the buttons, I use the following code:

Button(self,text="1",command=lambda: self.addkey("1"),width=self.defaultwidth,height=self.defaultheight).grid(row=5, column=0) Button(self,text="2",command=lambda: self.addkey("2"),width=self.defaultwidth,height=self.defaultheight).grid(row=5, column=1) Button(self,text="3",command=lambda: self.addkey("3"),width=self.defaultwidth,height=self.defaultheight).grid(row=5, column=2) 

The next command is called

 def addkey(self,key): # Adds a given key to the display if len(self.displaytext) + len(key) <= self.maxlength: self.displaytext += key self.display["text"] = self.displaytext 

When buttons 1, 2 and 3 are pressed in this order, the following result is displayed:

 123 

I am trying to clear the code so that it looks more like:

 for i in range(3): Button(self,text=str(i+1),command=lambda: self.addkey(str(i+1)),width=self.defaultwidth,height=self.defaultheight).grid(row=5, column=i) 

This adds the buttons in order, but when 1, 2, and 3 are pressed in that order, the following appears on the screen:

 333 

I was wondering if I missed something or it is simply impossible.

+2
source share
1 answer

Ah, a review. When you do this:

 command=lambda: self.addkey(str(i)) 

You do not "allow" i to a number right there and then . You just tell lambda to refer to i when it is called, afterwards .

Anytime since the end of the for loop, i = 3 (the last value), so all your lambdas get 3 when they request i .

If I'm not mistaken, you can add a function as a means of indirection, and it will β€œcapture” i from the surrounding area accordingly.

 def add_key_f(i): return lambda self: self.addkey(i) 
+5
source

Source: https://habr.com/ru/post/1491588/


All Articles