使用 tkinter 在带有 for 语句的标签中显示图片,可以吗?
问题描述
我正在尝试并排打印随机一堆图片;问题是,如果我运行以下代码,所发生的只是它创建了一组空白的空标签.如果我用text = 'whatever'"替换'image = pic',它工作正常(从而证明它实际上创建了标签).将标签和图像放在其他任何地方都可以正常工作(证明它不是图像),即使我使用 'pic = PhotoImage(file=w[0])' 它也可以(所以我不认为这是我的方法)...
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.
解决方案
这是 tkinter 的一个众所周知的问题 - 你必须保留自己对所有 Photoimages 的引用,否则 python 会垃圾收集它们 - 这就是你的图像所发生的事情.仅仅将它们设置为标签的图像不会增加图像对象的引用计数.
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.
要解决此问题,您需要对您创建的所有图像对象进行持久引用.理想情况下,这将是类命名空间中的数据结构,但由于您没有使用任何类,因此必须使用模块级列表:
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
相关文章