【问题标题】:Why does value storage effect the functionality of Tkinter?为什么价值存储会影响 Tkinter 的功能?
【发布时间】:2021-08-09 08:46:52
【问题描述】:

当我注意到一些非常奇怪的行为时,我试图用 Tkinter 在其中放置带有图像的按钮。举个例子:

此代码有效:

import tkinter as tk

root = tk.Tk()
root.geometry('720x480')
toolbar = tk.Frame(root, height=32)
toolbar.pack()

button1 = tk.Button(toolbar, text="1")
img1 = tk.PhotoImage(file="img1.png")
button1.config(image=img1)
button1.pack(side=tk.LEFT)

这段代码没有:(区别在倒数第二行)

import tkinter as tk

root = tk.Tk()
root.geometry('720x480')
toolbar = tk.Frame(root, height=32)
toolbar.pack()

button1 = tk.Button(toolbar, text="1")
button1.config(image=tk.PhotoImage(file="img1.png"))
button1.pack(side=tk.LEFT)

什么?为什么tk.PhotoImage(file="img1.png") 的值是否存储在变量中很重要,button1.config(image= 在一天结束时会收到相同的东西,不管它是如何到达那里的。

此外,这些图像的竞争变量名称似乎也会导致错误,见下文:

这行得通:

import tkinter as tk

root = tk.Tk()
root.geometry('720x480')
toolbar = tk.Frame(root, height=32)
toolbar.pack()

button1 = tk.Button(toolbar, text="1")
img1 = tk.PhotoImage(file="img1.png")
button1.config(image=img1)
button1.pack(side=tk.LEFT)

button2 = tk.Button(toolbar, text="2")
img2 = tk.PhotoImage(file="img2.png")
button2.config(image=img2)
button2.pack(side=tk.LEFT)

root.mainloop()

这不会:(只有第二个按钮获取图像)

import tkinter as tk

root = tk.Tk()
root.geometry('720x480')
toolbar = tk.Frame(root, height=32)
toolbar.pack()

button1 = tk.Button(toolbar, text="1")
img = tk.PhotoImage(file="img1.png")
button1.config(image=img)
button1.pack(side=tk.LEFT)

button2 = tk.Button(toolbar, text="2")
img = tk.PhotoImage(file="img2.png")
button2.config(image=img)
button2.pack(side=tk.LEFT)

root.mainloop()

非常感谢解释为什么将这些值存储在变量中而不是直接传递给函数会产生任何影响。

编辑:

更多怪事...

这行得通:

import tkinter as tk

root = tk.Tk()
root.geometry('720x480')
toolbar = tk.Frame(root, height=32)
toolbar.pack()

button1 = tk.Button(toolbar, text="1")
img1 = tk.PhotoImage(file="img1.png")
button1.config(image=img1)
button1.pack(side=tk.LEFT)

root.mainloop()

这不是:

import tkinter as tk

root = tk.Tk()
root.geometry('720x480')
toolbar = tk.Frame(root, height=32)
toolbar.pack()


def add_button(frame, txt, im_file):
    button = tk.Button(frame, text=txt)
    img = tk.PhotoImage(file=im_file)
    button.config(image=img)
    button.pack(side=tk.LEFT)

add_button(toolbar, 1, 'img1.png')

root.mainloop()

【问题讨论】:

    标签: python tkinter


    【解决方案1】:

    我天真地认为 python 垃圾收集器不可能是问题,因为在我使用 python 编程的 5 年中,我从来没有遇到过任何问题,但一切都是第一次 :)

    问题是 GC 将图像扔掉,可能是因为该图像在 python 中没有严格使用,而是通过某种绑定传递给 C,因此 GC 稍后能够“错过”它的使用并扔掉它离开(我猜)。无论如何,通过强制垃圾收集器保留它,问题就消失了(这就是为什么在变量中命名它会保留它),这是最容易使用列表完成的:

    import tkinter as tk
    
    root = tk.Tk()
    root.geometry('720x480')
    toolbar = tk.Frame(root, height=32)
    toolbar.pack()
    
    im_lst = []
    
    def add_button(frame, txt, im_file, im_lst):
        button = tk.Button(frame, text=txt)
        im_lst.append(tk.PhotoImage(file=im_file))
        button.config(image=im_lst[-1])
        button.pack(side=tk.LEFT)
    
    add_button(toolbar, 1, 'img1.png', im_lst)
    add_button(toolbar, 2, 'img2.png', im_lst)
    

    相关问题:

    Simple GUI with images

    Python, tkinter: Why is this jpeg not showing?

    Python Tkinter PhotoImage

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-26
    • 1970-01-01
    • 2019-04-25
    • 2020-07-23
    • 2012-05-11
    • 2011-04-03
    相关资源
    最近更新 更多