Trying to put images from a folder onto tkinter buttons. Only the last image is displayed

六眼飞鱼酱① 提交于 2021-02-15 07:41:34

问题


I'm trying to make a memory card matching game in python and I have a folder called 'icons' that has the 21 images that I want to use.

I created the buttons in a 6x7 grid using for loops. I put the buttons in a list called buttons which I will later use to keep track of which buttons are still empty and are available for putting images.

Using a for loop, I loop over the images in the folder. For each image, I choose a random button from the list which will contain the image. I then remove that button from the buttons list so that it is not chosen again. I do that twice for each image. Here is my code:

from tkinter import *
from pathlib import Path
import random

root = Tk()
root.geometry('600x700')
root.title('Memory Game')
icon_dir = Path('C:\\Users\\Talal\\PycharmProjects\\HelloWorld\\icons')
frm_grid = Frame(root)
frm_grid.rowconfigure([0, 1, 2, 3, 4, 5, 6], weight=1, minsize=2)
frm_grid.columnconfigure([0, 1, 2, 3, 4, 5], weight=1, minsize=2)
frm_grid.pack(fill=BOTH, expand=YES)
buttons = []
for row in range(0, 7):
    for column in range(0, 6):
        btn = Button(frm_grid)
        btn.grid(row=row, column=column, sticky='news')
        buttons.append(btn)
for file in icon_dir.iterdir():
    icon = PhotoImage(file=str(file))
    btn = random.choice(buttons)
    btn.config(image=icon)
    buttons.remove(btn)
    btn = random.choice(buttons)
    btn.config(image=icon)
    buttons.remove(btn)
root.mainloop()

However, when the code is executed, only the last image in the folder is displayed. It does display twice on two random buttons every time, so at least it displays correctly.

I wanted to show you a picture, but I am new to Stack Overflow so I unfortunately am not allowed do that yet, so I will describe it. There is a 6x7 grid of buttons in the window. every time I run the program, the last image in the folder is displayed on only 2 buttons, and the rest are empty.

I tried changing the order of the images in the folder to make sure it wasn't related to that specific image, but when I moved them, the new one displayed.

Thank you in advance!


回答1:


Since you used same variable icon to hold the reference of PhotoImage instances, so only the final image has variable reference to it. The other images will then be garbage collected.

Add btn.image = icon after each btn.config(image=icon) to keep a reference of the image:

for file in icon_dir.iterdir():
    icon = PhotoImage(file=str(file))
    btn = random.choice(buttons)
    btn.config(image=icon)
    btn.image = icon   # keep a reference to the image
    buttons.remove(btn)
    btn = random.choice(buttons)
    btn.config(image=icon)
    btn.image = icon   # keep a reference to the image
    buttons.remove(btn)



回答2:


This line: for file in icon_dir.iterdir():, you are systematically iterating over each image in the directory one after the other, You need to select the images at random from the directory not sequentially.

It goes like this:

/icon_dir
 |_img1
 |_img2
 |_img3

First it assigns img1 to two buttons and removes them, then it assigns img2 to two buttons and removes them then it assigns img3(aka the last image in the folder) to the displayed buttons which you see.

You can use this random.choice(os.listdir(icon_dir)) to get a random image



来源:https://stackoverflow.com/questions/62696252/trying-to-put-images-from-a-folder-onto-tkinter-buttons-only-the-last-image-is

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!