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

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

图像没有出现,我只有一张空白 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/

相关文章:

python - 列出 Django 中的所有静态 Assets

python - 能够删除具有特定对象标签 tkinter 的所有项目

python - 在 Tkinter 中调整滚动条高度?

python - 全部导入 不全部导入

swift - 如何让 Rx 值汇意识到过时的响应?

go - 如何正确使用sync.Cond?

ios - 核心数据和竞争条件

python - django - or_ 未定义

python - Moses v1.0 多语言ini文件

python - 在 Alembic 降级中删除外键?