Getting text from specific entry box in a grid and updating a combobox in that same row

Viewed 39

I am using a for loop to create my text boxes and comboboxes. I need to be able to change the text in my Text box (entry), then call a function to update the items in the combobox. Here is the code I am using.

def updatelist(updated_Num):
    ...
    ...
    new_list = [{'a':1},{'b':2},{'c':3}]

options = tk.StringVar(root)
for row, data in enumerate(all_data):
    entry = tk.Text(root, height=1.5, width=15)
    entry.bind('<Return>', lambda event: updateList(updated_Num=entry.get('1.0', 'end-1c')))
    entry.grid(row=row, column=1)

    options = [x for x in data[2]]
    variable.set(options[0])
    combobox = tk.ttk.Combobox(root, value=options, state='readonly')
    combobox.current(0)
    combobox.grid(row=row, column=2)

The problem I am having is that it always grabs the text from the LAST entry box created, and it deletes the text from whichever entry box I pressed enter from.

How do I get the text from the specific text box that I entered data into, as well as update the options for the combobox in that row?

edit: This is now working exactly how I want it to. Thanks for the help!

def updatelist(updated_Num, row):
    ...
    ...
    new_list = [{'a':1},{'b':2},{'c':3}]

    options = tk.StringVar(root)
    options = [x for x in new_list]
    variable.set(options[0])
    combobox = tk.ttk.Combobox(root, value=options, state='readonly')
    combobox.current(0)
    combobox.grid(row=row, column=2)

options = tk.StringVar(root)
for row, data in enumerate(all_data):
    entry = tk.Text(root, height=1.5, width=15)
    entry.bind('<Return>', lambda event, entry=entry, row=row: updateList(updated_Num=entry.get('1.0', 'end-1c'), row=row))
    entry.grid(row=row, column=1)

    options = [x for x in data[2]]
    variable.set(options[0])
    combobox = tk.ttk.Combobox(root, value=options, state='readonly')
    combobox.current(0)
    combobox.grid(row=row, column=2)
1 Answers

The problem is the way you create the lambda function in the for-loop. It's creating a closure to the value of entry, which at the end of the loop is the last entry box created. A common way to fix it is to give the lambda a default argument:

for row, data in enumerate(all_data):
    entry = tk.Text(root, height=1.5, width=15)
    entry.bind('<Return>', 
               lambda event, entry=entry: updateList(updated_Num=entry.get('1.0', 'end-1c')))
    entry.grid(row=row, column=1)

This is a fairly common problem folks have creating tkinter widgets in a loop, so your question may get closed as a duplicate.

Related