0

Here's some (python 3) code:

from tkinter import *

def makeButtons():
    global mainFrame
    listy = ["a", "b", "c"]
    dicty = {"a":["1", "2", "3"], "b":["4", "5", "6", "7"], "c":["8", "9"]}
    buttons = []
    for x, item in enumerate(listy):
        for y, value in enumerate(dicty[item]):
            btn=Button(mainFrame, text=value)
            btn.grid(column=x, row=y)
            buttons.append(btn)
    for i, but in enumerate(buttons):
        text = buttons[i]["text"]
        but.config(command=lambda *a: vocabMode(i, text))

def vocabMode(i, text):
    print(i, text)

root = Tk()
mainFrame = Frame(root)
mainFrame.grid(column=1, row=2)
makeButtons()
root.mainloop()

Go ahead, run it. It works. Except for one small thing.

I'm expecting it to print the text of the label. But no matter what I try, it always prints the value of the last button created. I can't find a solution anywhere when I want it to print its own value. Thanks for the help.

Edit: It has been claimed that this is a duplicate of Generating functions inside loop with lambda expression in python. I'm not sure how. The answers there don't resolve my issues, or if they do, the relationship is too abstract for me to understand.

Community
  • 1
  • 1
boristhescot
  • 129
  • 2
  • 11
  • I acknowledge some goofiness in the code. They are relics from creating the snippette. – boristhescot Mar 25 '16 at 22:15
  • 1
    Your problem here and the dupe target are same. If those answers didn't explained enough, going through _linked_ questions might help as well. And for the solution, just add default values to your lambda. `command= lambda i=i, text=text: vocabMode(i, text)` – Lafexlos Mar 25 '16 at 22:48
  • 1
    While maybe not the best choice of a duplicate, this question is a duplicate of many, many questions. This sort of thing gets asked all the time. Don't look at the accepted answer to that question, look at this one: http://stackoverflow.com/a/1841368/7432 or maybe this one: http://stackoverflow.com/a/33984811/7432 or maybe this one: http://stackoverflow.com/a/7546960/7432 or maybe this one: http://stackoverflow.com/a/2295368/7432 – Bryan Oakley Mar 25 '16 at 22:50
  • "It has been claimed that this is a duplicate of Generating functions inside loop with lambda expression in python. I'm not sure how." In this case, `for i, but in enumerate(buttons):` is the loop, and `lambda *a: vocabMode(i, text)` is the lambda expression that generates functions. The problem occurs, as explained there and in many other places, because the lambda uses `i`, which comes from the iteration. The solution is to bind it explicitly, as described in those answers, using the techniques shown there. – Karl Knechtel Aug 19 '22 at 12:19

0 Answers0