Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
389 views
in Technique[技术] by (71.8m points)

Tkinter in Python 3.8.5 : Having an issue creating multiple images as buttons within a function

I'm currently having an issue with tkinter/python. I'm trying to create buttons with images within a for-loop. I've done some reading on here about others having a similar issue and it was resolved by setting a global variable. The issue I am having is that when I create the grid layout for my buttons the image is only applied to the last button as the global variable is being overwritten. I'm pretty new to python/coding in general so I don't even know if I'm going about it the right way. I'd like to be able to dynamically create the buttons/images so that I can items more easily in the future without having to hard code them. Any advice is appreciated, thank you!

 def OnRaidMaterialClick(raidMaterial, raidConstruction):
    global imgVar
    rowCounter = 0
    columnCounter = 0  
    
    for attr, value in raidConstruction.__dict__.items():
        
        labelVar = Label(root, text = value['name'])
        imgVar = ImageTk.PhotoImage(Image.open(value['image']))
        buttonVar = Button(root, text = value['name'], 
                           image = imgVar, 
                           compound = TOP).grid(row = rowCounter, column = columnCounter)
        
        if columnCounter < 3:
            columnCounter += 1
        
        if columnCounter == 3:
            columnCounter = 0
            rowCounter += 1
        
        if rowCounter == 3:
            rowCounter = 0

The code runs and compiles ok, I have the grid layout I'd like, but the only image that shows is the last image in the grid.

I've looked into creating dynamic variables but was told that is bad practice so I'm trying to avoid that. I've read that dictionaries are the way to go but I can't figure out how to apply that data structure to my problem and come up with a working solution.

Any ideas?


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

You can save the reference of the image instance to an attribute of the button:

for attr, value in raidConstruction.__dict__.items():
    labelVar = Label(root, text=value['name'])
    imgVar = ImageTk.PhotoImage(file=value['image'])
    buttonVar = Button(root, text=value['name'], image=imgVar, compound=TOP)
    buttonVar.grid(row=rowCounter, column=columnCounter)
    buttonVar.image = imgVar  # save the image reference to an attribute of button
    ...

Note that global imgVar is not necessary and can be removed.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...