Python tkinter 代码在函数内部时不运行

Posted

技术标签:

【中文标题】Python tkinter 代码在函数内部时不运行【英文标题】:Python tkinter code doesn't run when inside a function 【发布时间】:2020-12-11 18:54:34 【问题描述】:
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,而不是两者。此外,将图像与您要加载的任何其他图像一起存储在全局字典中。按照您的操作方式,您的图像是垃圾收集的主要候选对象。 您能说得更具体些吗?当它起作用时究竟会发生什么(例如,你期望它做什么),当它不起作用时会发生什么?是否有任何错误消息? @MichaelGuidry 这不会有任何区别 @AryanParekh - 我对垃圾收集的编辑可能会。 @MichaelGuidry 我不确定,因为在根目录中有对该标签的引用,我认为,所以垃圾收集器不应该删除它.... 【参考方案1】:

您的图像正在被垃圾收集。这行得通。

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

【讨论】:

Legend,完美运行,我从不知道您可以将位置作为参数传递给函数。为什么要在Images 之前加上*,这只是约定吗? 使用[*SomeDict]等价于SomeDict.keys() 实际上,这是没用的,因为 dicts 已经检查了键中的包含,这意味着 a in some_dict.keys() == a in some_dict @BlackBeans ~ 大声笑,我总是忘记是key in dict: 还是value in dict 所以,我只是说得具体一点。也许您的评论会留在我的脑海中作为提醒。 你好,现在图像在函数内部不会出现,但是在函数外部可以正常工作。 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_mainfinale = tk.Label(root, image=image_1)finale.pack()wow = tk.Label(root, text = 'its a match')wow.pack()

以上是关于Python tkinter 代码在函数内部时不运行的主要内容,如果未能解决你的问题,请参考以下文章

Tkinter 退出时不更新

代码在函数内部时不运行

python使用tkinter实现透明窗体上绘制随机出现的小球(第二篇)

Tkinter PIL 图像未显示在函数内部

Windows 上 Python 3.4 中的 Tkinter 不会在退出时将内部剪贴板数据发布到 Windows 剪贴板

Tkinter Python程序中函数参数的名称错误