在TKinter中创建图像时可能出现的竞争条件?

时间:2014-04-11 15:44:18

标签: python tkinter race-condition

为了好玩,我正在使用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()

图像没有出现,我所拥有的只是一块空白的画布。我觉得这很奇怪,所以我开始玩,看看为什么会这样。我的下一步是测试我知道如何创建图像,所以我只是将我的文件创建为基本图像:

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()

这没有画出来。我再次留下一块空白的画布。这让我怀疑可能在幕后发生了一些奇怪的线程问题。有谁知道为什么第二个片段有效并且第三个片段失败了?

1 个答案:

答案 0 :(得分:3)

我已经看到number of times already了。问题是PhotoImage是垃圾收集,即使Label中使用了它!要解决此问题,只需将其绑定到GUI本身的成员变量:

self.photo = ImageTk.PhotoImage(file="flappy.gif")
self.bird = self.canvas.create_image(x,y,image=self.photo)

它在第二个示例中起作用的原因是img变量在mainloop方法完成之后才存在,而在第三个示例中,它仅在创建{{1}时存在}}