代码之家  ›  专栏  ›  技术社区  ›  Jellicle

无法在mainloop中创建新映像

  •  -1
  • Jellicle  · 技术社区  · 6 年前

    我有一个很长的图像列表,我想加载到一个 Tkinter

    PIL.PhotoImage 调用前的实例 mainloop 以我的特金特为例。我将以下内容放入绑定到按键或类似事件的回调函数中:

    def onkeypress( event )
      canvas.itemconfig( canvas_image, image_content )
    
    image_content = PIL.PhotoImage( file="myfile.jpg" )
    mytk.bind( "<Key>", onkeypress )
    mytk.mainloop()
    

    只在我需要的时候:

    def onkeypress( event )
      image_content = PIL.PhotoImage( file="myfile.jpg" )
      canvas.itemconfig( canvas_image, image_content )
    
    mytk.bind( "<Key>", onkeypress )
    mytk.mainloop()
    

    我需要做什么才能改变画布的内容?

    2 回复  |  直到 6 年前
        1
  •  -1
  •   Sraw    6 年前

    这是因为 tk 不会保存该图像对象的引用,因此GC将在函数作用域之后收集它 image_content 是最后一个引用,它消失了。

        2
  •  1
  •   Mike - SMT    6 年前

    我能看到的第一个问题是 mainloop() 在关闭tkinter实例之前,不能在mainloop之后运行任何操作。因此,您需要将函数移到mainloop和绑定之上。另一个重要问题是函数中的局部变量。您的函数创建了一个本地映像,该映像将在函数完成后消失,因此您需要定义 image_content 作为函数中的全局变量。

    下面是一个简单的示例,说明如何将引用保存为图像,并在需要时随时使用按钮应用它们。

    import tkinter as tk
    from PIL import ImageTk
    
    
    root = tk.Tk()
    
    def change_color(img_path):
        global current_image
        current_image = ImageTk.PhotoImage(file=img_path)
        lbl.config(image=current_image)
    
    
    current_image = ImageTk.PhotoImage(file="red.gif")
    lbl = tk.Label(root, image=current_image)
    lbl.grid(row=0, column=0, columnspan=3)
    
    tk.Button(root, text="RED", command=lambda: change_color("red.gif")).grid(row=1, column=0)
    tk.Button(root, text="BLUE", command=lambda: change_color("blue.gif")).grid(row=1, column=1)
    tk.Button(root, text="GREEN", command=lambda: change_color("green.gif")).grid(row=1, column=2)
    
    root.mainloop()
    

    enter image description here enter image description here enter image description here