0

So I'm remaking a browser game where you guess a Pokémon based on its cry from the games. I have the main part of the quiz game done, but I want to make a cheat sheet to go with it. The cheat sheet is just 15 rows of ten Pokémon(buttons with the images of the Pokémon on them), and clicking on them will play their cry. What I want to do is make a for loop, where as long as x > 152 (the # of original Pokémon + 1), the loop will create images of each Pokémon at specific places. My problem is that a single instance of a PhotoImage will be updated when a new image is applied to it, leaving the space before it blank.

def cheatsheet():                                                 
    sheet = Toplevel()                                            
    sheet.title("Pokédex of Cries")                               
    sheet.geometry("1000x500")                                    
    sheet.resizable(False, True)                                  
     

    #mon keeps track of the Pokémon's dex number
                                                           
    mon = 1                                                       
    xpos = 20                                                     
    ypos = 20                                                     
    in_row = 0                

    #this loops 151 times
                                        
    while mon < 152:                                                
        
        #this makes a new row every ten spaces
                                                          
        if in_row == 10:                                          
            ypos += 84                                            
            xpos = 20                                             
            in_row = 0                                            
           
        #this is where I encounter problems. monImage is a single instance of a 
        #PhotoImage, and when the loop reiterates, monImage leaves the button before it 
        #completely blank. I have tested it and making a monImage2 does leave two buttons 
        #with images, but I would have to make 151 separate monImages.
                                                       
        monImage = PhotoImage(file=str(mon) + ".png")     
        Button(sheet, image=monImage).place(x=xpos+101, y=ypos)
                                                                                                                                    
        mon += 1                                                  
        in_row += 1                                               
        xpos += 101                                               
                                                                  
    sheet.mainloop()

Is there any way I can dynamically update the name of monImage to something like monImage2 during the for loop, thus creating a separate instance and multiple images? This isn't me being lazy, either, I've had to make a dictionary for each Pokémon's cry wav, rename a bunch of files one by one etc. I'm willing to put in the work, but if this automated method is possible to do, I want to know it to improve my programming for the future.

I have checked around for another question like this. I found someone else with my exact same problem and looking for the exact same solution. Except they were making a card game, and they would've only needed to make 52 images for the cards instead of 151 images for all the Pokémon. Their question wasn't answered, as they did not explain the problem well enough(which is why this post is so concise, I don't want it to be confusing).

If my solution isn't feasible but there is another solution, please share that too. I'm willing to rewrite this code, its not too much to rewrite anyway.

Lastly, I apologize if this is code sickening to look at. I am very new, I started three days ago and this is my first project. Thanks in advance.

codester_09
  • 5,622
  • 2
  • 5
  • 27
  • One of the way is to use a list to store the instances of the images. – acw1668 Jun 20 '22 at 15:17
  • Does this answer your question? [Why does Tkinter image not show up if created in a function?](https://stackoverflow.com/questions/16424091/why-does-tkinter-image-not-show-up-if-created-in-a-function) – jasonharper Jun 20 '22 at 15:17
  • @jasonharper It is not the same issue. The issue is that OP use same variable for storing the references of images, so only the last one will be shown. – acw1668 Jun 20 '22 at 15:26

1 Answers1

0

Any way of keeping a reference to the image in the next iteration of the loop would work. The simplest would be to append each image to a list as you create it:

def cheatsheet():
    ...
    # List of images - used to maintain a reference to each image so they aren't garbage collected
    imageRefs = []
    while mon < 152:
        ...
        imageRefs.append(monImage)
    ...

There is technically a way to dynamically change the name of the variable being created as you suggested, but there's no reason to do it that way. On a basic level, being able to programmatically manipulate a series of similar variables is the purpose of lists.

Anonymous12358
  • 436
  • 1
  • 10
  • For some reason, I assumed you could not make a list of images. I'm not sure why, but that pretense is abolished thanks to you. Worked like a charm. – Quincy Pettaway Jun 20 '22 at 22:15