1

Using Tkinter in python, trying to make numbered buttons, which use self.do(x) to add the number x to a string variable. The problem with this particular piece of code being in a loop (to save space), is that it will add the LAST number to the string (ie, 9 in this example). This is because it calls the function after this, and uses the latest value of num[i]. Is there any way to correct this?

self.numButton = []
num = []
for i in range(9):
    num.append(i + 1)
    self.numButton.append(Button(root,text=num[i],command=lambda: self.do(num[i])))
2
  • That long line is pretty hard to read. Can you break it out into more than one line or create a function to remove the inessential parts from the question? Commented Sep 22, 2013 at 1:19
  • There you go, the length is pretty essential, but I took out the parts that are not generally required. Commented Sep 22, 2013 at 1:21

1 Answer 1

1

Use a default value in your lambda function:

self.numButton.append(
    Button(root,text=num[i],command=lambda i=i: self.do(num[i])))

The default value is evaluated and bound to the function at the time the lambda function is defined (as opposed to when it is run). So, later, when the button is pressed and the callback is called without any arguments, the default value is used.

Since a different default value for i is bound to each lambda function, the appropriate value for i is used for each callback.


If the callback requires additional arguments, such as on event, just place the parameter with default value at the end. For example,

root.bind('Key-{n}'.format(n=num[i]), lambda e, i=i: self.do(num[i]))
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks alot, I knew I was missing something. As an extension to the question, how would I bind self.do(x) to a key, when I simultaneously need lambda e: and lambda i=i: ? 'root.bind(str(num[i]),lambda e: self.do(num[i]))'
root.bind('Key-{n}'.format(n=num[i]), lambda e, i=i: self.do(num[i]))

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.