Python tkinter在函数内运行时无法运行

3
def display_rain():
    rain_image = Image.open("./images/rain_jpeg.jpg")
    rain_resized = rain_image.resize((250,250), Image.ANTIALIAS)
    rain_tk = ImageTk.PhotoImage(rain_resized)
    rain_label = tk.Label(root, image = rain_tk)
    rain_label.grid(row = 0, column = 0)
    rain_label.pack()

display_rain()

代码在函数外部运行良好,但在函数内部似乎根本没有运行。我已经尝试重启 Python 并重新命名该函数。

在函数的第一行添加“global root”,看看会发生什么。此外,选择packgrid中的一个,不要同时使用两者。还要将图像与您想要加载的任何其他图像存储在全局字典中。按照您目前的方式,您的图像很可能被垃圾回收。 - OneMadGypsy
请问您能否更具体一些?当它工作时会发生什么(例如,您期望它做什么),而当它不工作时会发生什么?是否有任何错误信息? - jthulhu
@MichaelGuidry 那不会有任何区别。 - user14248283
@AryanParekh - 我关于垃圾回收的编辑可能会有所帮助。 - OneMadGypsy
@MichaelGuidry 我不确定,因为在根中有对该标签的引用,所以垃圾收集器不应该将其删除... - jthulhu
1个回答

3

您的图像正在进行垃圾回收。这是有效的。

import tkinter as tk
from PIL import Image, ImageTk


root = tk.Tk()
root.geometry("800x600")

#store all images in this dict so garbage collection will leave them alone
#it doesn't have to be named "images"; it just has to be a dict
images = dict()


def display_rain(row=0, column=0):
    #create and store the image if it doesn't exist
    if 'rain_tk' not in images:
        #unless you are making mips of this image you should probably  
        #~make it the proper size and get rid of the resize part
        image = Image.open("./images/rain_jpeg.jpg").resize((250,250), Image.ANTIALIAS)
        #you can add a name to reference the image by
        #this makes it cleaner than accessing the dict directly
        images['rain_tk'] = ImageTk.PhotoImage(image, name='rain')
        
    #make and return the label, in case you want to grid_forget it or change the image
    label = tk.Label(root, image='rain') #instead of image=images['rain_tk']
    label.grid(row=row, column=column)
    return label
    
#you can easily display this wherever you want by filling in the row and column arguments
#as an example, this would be displayed at row1 column2
rain_lbl = display_rain(1, 2)
      
root.mainloop() 

1
传奇,它完美地工作了,我从来不知道你可以将位置作为参数传递给函数。你为什么在Images之前加上了一个*,那只是惯例吗? - Benjamin McDowell
使用 [*SomeDict] 等同于 SomeDict.keys() - OneMadGypsy
实际上,这是无用的,因为字典已经在键中检查包含性,这意味着a in some_dict.keys() == a in some_dict - jthulhu
@BlackBeans ~ 哈哈,我总是忘记是 key in dict: 还是 value in dict,所以我只会具体地写。也许你的评论会成为我的提醒。 - OneMadGypsy
你好,现在当图像在函数内部时不会出现,但是当在函数外部时,它可以完美地工作。weather_main = 'Clouds'if weather_main + '_tk' not in [*Images]: wow = tk.Label(root, text = 'its a match') wow.pack() image_1 = ImageTk.PhotoImage(Image.open("./images/" + weather_main + ".jpg")) Images["main_type"] = weather_main finale = tk.Label(root, image=image_1) finale.pack() wow = tk.Label(root, text = 'its a match') wow.pack() - Benjamin McDowell
@BenjaminMcDowell,你正在将单词“Clouds”保存在Images中。请执行以下操作:Images['main_type'] = image_1image=Images['main_type'] - OneMadGypsy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接