0

I want to create a for loop such that during each iteration of it, a new variable is created. I then want to be able to run commands on the new variable within that for loop so that I can form tkinter Buttons out of the new variables.

Example,

for i in range(0,17):
    #Should create variables Button1, Button2, Button3 and so on.
    Button+str(i)=tk.Button(root, image=img, command=lambda: changebg(i))
    Button+str(i).grid(column=0, row=0)

The reason I want to do this is I want to put 16 images into a tkinter frame and want each button to be mapped to a different image such that when the button is clicked the root window background is set as the image of the button clicked. Earlier, I created a for loop that created 16 buttons but each button was stored in the variable “Button” and hence the command to them was modified each time. Atleast I think it was because any button I clicked changed the background to the last image created. I’ve scrapped that code now. If you want it for reference here it is,

for imgphoto in (imagedict.keys()):
    imgbtnphoto=Image.open(imgphoto)
    imgbtnphoto.thumbnail((120,120))
    buttonphoto= ImageTk.PhotoImage(imgbtnphoto)
    GridColumn=imagedict[imgphoto]%4
    GridRow=imagedict[imgphoto]/4
    Button= tk.Button(root, image=buttonphoto, command=lambda: changebg(str(GridColumn)+str(GridRow)))
    Button.grid(column=GridColumn, row=GridRow)
    Button.image=buttonphoto

At the moment, my new code has become too complicated for me to post just a part of it as an example and not have a huge chunk of my source code exposed to the internet. So if anybody doesn’t understand my query please ask me to explain further. Also if there is an alternate way to do this other than the way I specified I would gladly entertain that suggestion.

Thanks :)

Sharpfawkes
  • 549
  • 1
  • 8
  • 15

2 Answers2

1

Why not use a list to store the references on the buttons like:

buttons = []
buttonphotos = []
# here goes your loop
for imgphoto in (imagedict.keys()):
    buttonphotos.append(Image.open(imgphoto).thumbnail((120,120)))
    # [...] some of your actions
    # access buttonphoto by using last elem index
    # buttonphotos[-1]
    buttons.append(tk.Button(root, [...])) # pseudo code line
    buttons[-1].grid([...]) # pseudo code line
R4PH43L
  • 2,122
  • 3
  • 18
  • 30
0

Do not create dynamic variable names. It makes your code almost impossible to read.

A simple solution is to use a dictionary, with the name as the key:

buttons = {}
for i in range(0,17):
    name = "Button" + str(i)
    buttons[name] = tk.Button(...)
    ...

Later, if you want to update the button you can reference it like:

buttons["Button1"].configure(...)
Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685
  • Based off of raphael's suggestion i did this. However, the image for them still defaults to the image of the last button created. If I configure the button to have a lambda command that takes an argument (say variable Index) and this variable changes throughout the course of the for loop, would the value of Index change in every single button during every single iteration of the for loop. I ask this because when the function is called, I have ask it to print the value of Index. When i click every button, all of them print the Index value as 17 (which is in fact the last value of Index) – Sharpfawkes Apr 21 '16 at 14:39
  • 1
    @LeroyJD: there are lots of questions and answers about creating buttons and images in a loop on this site. For example, http://stackoverflow.com/questions/28494089/how-to-understand-closure-in-python-lambda – Bryan Oakley Apr 21 '16 at 15:13
  • That is exactly what I needed – Sharpfawkes Apr 21 '16 at 18:07