我有一个相当长的GUI图像查看程序,“全局变量”开始失控,除了一个,我已经将它们全部消除。下面的简化代码显示了全局变量的艺术。将其安装到位后,图像将显示出来,而没有显示-灰色屏幕。希望能帮助您了解正在发生的事情
from tkinter import *
from PIL import ImageTk,Image
root = Tk()
def image():
global art
path="c:/Google Drive/Art Images/0030#Van Tromp, going about to please his Masters.jpg"
image=Image.open(path)
art = ImageTk.PhotoImage(image)
label.grid()
label.configure(image=art)
label=Label(root,bg="grey")
image()
root.mainloop()
您的问题是,在创建Photoimage
时,需要保留对该图像的引用,这意味着您需要为该图像分配一个变量名,该变量名可以在其他位置访问。在您的情况下,不使用全局变量的变量art
保留在函数中。这意味着当函数完成时,art
被破坏。一个简单的解决方法是返回变量art,从而输出函数art
,并将变量带入主代码。这是effbot必须说的:
当将PhotoImage或其他Image对象添加到Tkinter小部件时,必须保留对图像对象的引用。如果您不这样做,图像将不会总是显示。
问题是Tkinter / Tk界面无法处理对图像的引用正确反对; Tk小部件将保留对内部对象的引用,但Tkinter不会。当Python的垃圾收集器丢弃Tkinter对象时,Tkinter告诉Tk释放图像。但是由于小部件正在使用图片,因此Tk不会销毁它。不完全的。它只是使图像空白,使其完全透明
要解决此问题,您可以使用全局变量(可以在主代码中的其他位置访问该变量,从而成为'引用',或者可以执行以下操作:
from tkinter import *
from PIL import ImageTk,Image
root = Tk()
def image():
label.grid()
path="c:/Google Drive/Art Images/0030#Van Tromp, going about to please his Masters.jpg"
image=Image.open(path)
art = ImageTk.PhotoImage(image)
label.configure(image=art)
return art
label=Label(root,bg="grey")
image()
root.mainloop()
在该代码中,您的图像由函数返回并在主代码中分配了一个变量,使得它成为没有全局变量的“参考”。
您可以找到更多信息here
您的函数image()正在用于输出图像,为此,您将其分配给变量'art'。创建了一个图像对象,但是当您的函数结束时,由于您未返回任何内容,因此该对象不再存在:
y = 5
def getx():
x = 3
getx()
a = y + x
此代码将无效,因为x在函数getx()中是本地的。由于我对它不做任何事情,因此函数结束时,变量也是如此。但是,我可以做的是从函数中传递数据,如下所示:
y = 5
def getx():
x = 3
return x
x = getx()
a = y + x
在您的代码中,tkinter需要图像对象在运行时存在,但是在函数中创建图像对象时,无需对其执行任何操作即可结束该函数。为全局变量命名可以有效地使您的函数将您的对象返回到函数外部的变量。但是,另一种方式可以做到:
root = Tk()
def image():
path="c:/Google Drive/Art Images/0030#Van Tromp, going about Masters.jpg"
image=Image.open(path)
art = ImageTk.PhotoImage(image)
label.grid()
label.configure(image=art)
return art
label=Label(root,bg="grey")
art = image()
root.mainloop()