Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

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

python - Displaying pics in Labels with a for Statement using tkinter, can it be done?

I am trying to get a random bunch of pictures to print side by side; the problem is that if I run the following code all that happens is that it creates a group of blank empty labels. If I replace the 'image=pic' with a "text='whatever'" it works fine (thus proving that it dows actually create the label). Placing the label and image anywhere else works fine (proving that it's not the images), even if I use 'pic = PhotoImage(file=w[0])' it works (so I don't think its my method)...

from tkinter import *
from tkinter import ttk
import random

root = Tk()
root.title("RandomizedPic")

def randp(*args):
    w = ['wb.gif', 'wc.gif', 'wd.gif', 'we.gif']
    random.shuffle(w)
    am = 1

    for i in w:
        pic = PhotoImage(file=i)
        ttk.Label(mainframe, image=pic).grid(column=am, row=0, sticky=(W, E))
        am+=1


mainframe = ttk.Frame(root, padding="3 3 12 12")
mainframe.grid(column=0, row=0, sticky=(N, W, E, S))
mainframe.columnconfigure(0, weight=1)
mainframe.rowconfigure(0, weight=1)

ttk.Button(mainframe, text="Do it", command=randp).grid(column=0, row=0, sticky=W)

root.bind('<Return>', randp)
root.mainloop()

Any advice on how to get this to work will be much appreciated.

See Question&Answers more detail:os

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

1 Reply

0 votes
by (71.8m points)

This is a well-known issue with tkinter - you MUST keep your own reference to all Photoimages, otherwise python will garbage collect them - that's what's happening to your images. Merely setting them as the image for a label does NOT add to the reference count for the image objects.

SOLUTION:

To solve this problem, you'll need a persistent reference to all the image objects you create. Ideally, this would be a data structure in a class namespace, but since you aren't using any classes, a module-level list will have to do:

pics = [None, None, None, None]   #  This will be the list that will hold a reference to each of your PhotoImages.

def randp(*args):
    w = ['wb.gif', 'wc.gif', 'wd.gif', 'we.gif']
    random.shuffle(w)
    am = 1

    for k, i in enumerate(w):    # Enumerate provides an index for the pics list.
        pic = PhotoImage(file=i)
        pics[k] = pic      # Keep a reference to the PhotoImage in the list, so your PhotoImage does not get garbage-collected.
        ttk.Label(mainframe, image=pic).grid(column=am, row=0, sticky=(W, E))
        am+=1

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...