为了好玩,我正在使用 tkinter 创建一个蹩脚的直升机/flappybird 克隆,并且我遇到了一些关于图像显然没有显示的非常奇怪的行为。
(顺便说一句,使用 python3)
所以我从以下代码开始只是为了看看我是否可以开始绘制东西:
from tkinter import *
from PIL import ImageTk
class Bird(object):
def __init__(self, canvas, x=0, y=0):
self.canvas = canvas
photo = ImageTk.PhotoImage(file="flappy.gif")
self.bird = self.canvas.create_image(x,y,image=photo)
class Environment(Canvas):
def __init__(self, master, width=500, height=500):
super(Environment, self).__init__(master, width=width, height=height)
self.pack()
self.master = master
self.bird = Bird(self)
if __name__=="__main__":
r = Tk()
env = Environment(r)
env.pack()
r.mainloop()
图像没有出现,我只有一张空白 Canvas 。我觉得这很奇怪,所以我开始尝试看看为什么会出现这种情况。我的下一步是测试我是否知道如何创建图像,因此我只是将我的文件创建为基本图像:
if __name__=="__main__":
r,c=get_canv()
c.pack()
img = ImageTk.PhotoImage(file="flappy.gif")
c.create_image(100,100,image=img)
r.mainloop()
不出所料,这个效果很好。所以,我之前代码中的语法似乎是正确的。这是我偶然发现一些有点令人困惑的事情的时候:
if __name__=="__main__":
r,c=get_canv()
c.pack()
c.create_image(100,100,image=ImageTk.PhotoImage(file="flappy.gif"))
r.mainloop()
这没有画出来。我又只剩下一张空白的 Canvas 。这让我怀疑幕后可能存在一些奇怪的线程问题。有谁知道为什么第二个片段有效而第三个片段失败?
最佳答案
我见过这个number of times already 。问题是 PhotoImage
被垃圾收集,即使它被用在 Label
中!要解决这个问题,只需将其绑定(bind)到 GUI 本身的成员变量即可:
self.photo = ImageTk.PhotoImage(file="flappy.gif")
self.bird = self.canvas.create_image(x,y,image=self.photo)
它在第二个示例中起作用的原因是 img
变量一直存在,直到 mainloop
方法完成之后,而在第三个示例中,它仅在创建标签
。
关于python - 在 TKinter 中创建图像时可能出现竞争条件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23017049/