0

I'm working on making a front end of a database with python tkinter. To display the records, I use a for loop for fill out each row. In each row I'm trying to add a button that would open to that record information, but in every row's button would open to the last record. So that would indicate that the command for each button is being over written to the last value this could also mean that the buttons are not unique. I would like help in trying to generate a unique button for each loop or a solution to the instruction for the command from being over written.

list1 = ["t1", "t2", "t3"]
dcount=0
sizel=len(list1)
for x in range(0,sizel):
    button = Button(frame, text="test", command=lambda:action(frame,list1[x]))
    button.grid(row=dcount,column=0)
    dcount=dcount+1

Any help would be appreciated. I did see some solutions where they put values in front of lambda but I would not manage to get that to work.

piles fun
  • 11
  • 1
  • Do these help?: https://stackoverflow.com/questions/69334341/tkinter-create-clickable-labels-in-for-loop, https://stackoverflow.com/questions/17677649/tkinter-assign-button-command-in-a-for-loop-with-lambda, https://stackoverflow.com/questions/63172765/python-tkinter-bind-function-to-list-of-variables-in-a-for-loop, https://stackoverflow.com/questions/10865116/tkinter-creating-buttons-in-for-loop-passing-command-arguments and https://stackoverflow.com/questions/6181935/how-do-you-create-different-variable-names-while-in-a-loop – The Amateur Coder Jul 11 '22 at 05:25
  • Sorry, if I wasted anyone's time, but I Just figured out a solution. Which was to use functools.partial(). so that it looks something like x=functools.partial(action,frame,list1[x]). Then replace lambda with x. – piles fun Jul 11 '22 at 05:35

3 Answers3

0
list1 = ["t1", "t2", "t3"]
dcount=0
sizel=len(list1)
for x in range(0,sizel):
    y=functools.partial(action,frame,list1[x])
    button = Button(frame, text="test", command=y)
    button.grid(row=dcount,column=0)
    dcount=dcount+1

Sorry again if I wasted poeple's time. This is the solution i found. this post sparked the solution:How to pass arguments to a Button command in Tkinter?

piles fun
  • 11
  • 1
0

Following example worked for me.

import tkinter as tk

def func1():
    print(1)

def func2():
    print(2)

def func3():
    print(3)

root = tk.Tk()
funcList = [func1, func2, func3]
buttons = []

for x in range(len(funcList)):
    buttons.append(tk.Button(root, text="test", command=funcList[x]))
    buttons[x].grid(row=x, column=0)

root.mainloop()
Nova
  • 50
  • 8
  • This is very interesting, I did not consider using a list for the buttons. I will also try this one out. Thank you so much! – piles fun Jul 11 '22 at 07:26
0

Here is the simplest least-impacting change in your code:

button = Button(frame, text="test", command=lambda idx=x: action(frame, list1[idx]))

The problem was that you defined your lambda to take x, but it would take the current value of x, i.e. the last one. Instead, you need to specify that your parameter idx (or whatever you like) must take the value of x it sees during this specific loop iteration.

ALai
  • 739
  • 9
  • 18