为什么我的图像没有出现在 tkinter 中 canvas

Why is my image not showing up in tkinter canvas

我正在尝试 UI 将刺激作为学校评估的一部分。我试图在页面的顶部框架上导入提供的学校徽标和横幅,并将图像放在 canvas 上,但尚未取得任何结果。当我 运行 代码时,图片根本不会加载。我使用的代码如下:

from tkinter import *
import random
import time
import sqlite3
from tkinter import simpledialog
from tkinter import messagebox
from tkcalendar import *
from tkinter import ttk
import math
from PIL import Image, ImageTk
import winsound

#-------------Frames setup--------------------------
class VendingApp(Tk):
    def __init__(self):
        Tk.__init__(self)
        self._frame = None
        self.switch_frame(Home)

    def switch_frame(self, frame_class):
        #Destroys current frame and replaces it with a new one.
        new_frame = frame_class(self)
        if self._frame is not None:
            self._frame.destroy()
        self._frame = new_frame
        self._frame.pack()

####-----------------------Home page---------------------------
class Home(Frame):    
    def __init__(self, master):
        Frame.__init__(self, master)

        topFrame = Frame(self,width = 1024, height = 100, bd = 2, bg = "black")
        topFrame.pack()

        canvas_for_logo = Canvas(topFrame, height=100, width=100, bg = 'green') ##logo image
        canvas_for_logo.grid(row=0, column=0, sticky='ne')
        
        img_logo = Image.open("pic/sitelogo.png")
        img_logo = img_logo.resize((40,40), Image.ANTIALIAS)
        logo = ImageTk.PhotoImage(img_logo)
                                         
        canvas_for_logo.create_image(0, 0, anchor=NW, image=logo)


        canvas_for_banner = Canvas(topFrame, bg='red', height=100, width=924) #banner image
        canvas_for_banner.grid(row=0, column=1, sticky='nw')

        img_banner = Image.open("pic/banner.jpg")
        img_banner = img_banner.resize((40,40), Image.ANTIALIAS)
        banner = ImageTk.PhotoImage(img_banner)
                                         
        canvas_for_banner.create_image(0, 0, anchor=NW, image=banner)


        
        
        MidFrame = Frame(self,width = 1024, height = 628, bd = 2)
        MidFrame.pack()
        MidFrame.grid_propagate(False)



        BottomFrame = Frame(self,width = 1024, height = 50, bd = 2, bg = "black")
        BottomFrame.pack()
        BottomFrame.grid_propagate(False)
        

if __name__ == "__main__":
    root = VendingApp()
    #Sets the size of the window
    root.geometry("1024x768")
    #Renames the TITLE of the window
    root.title("Vending machine")
    root.geometry("1024x768")
    root.resizable(False, False) 


    root.mainloop()

我决定制作一个单独的文件来测试图像是否可以在没有 class 的情况下加载,并且确实如此。代码如下:

from tkinter import ttk
from tkinter import*
import time
from PIL import Image, ImageTk

root = Tk()

canvas_for_logo = Canvas(root, height=100, width=100)
canvas_for_logo.pack()

img = Image.open("pic/sitelogo.png")
img = img.resize((105,105), Image.ANTIALIAS)
logo = ImageTk.PhotoImage(img)
                                 
canvas_for_logo.create_image(0, 0, anchor=NW, image=logo)


canvas_for_banner = Canvas(root, bg='red', height=100, width=924) #banner image
canvas_for_banner.pack()

img_banner = Image.open("pic/banner.jpg")
img_banner = img_banner.resize((924,100), Image.ANTIALIAS)
banner = ImageTk.PhotoImage(img_banner)
                                 
canvas_for_banner.create_image(0, 0, anchor=NW, image=banner)

root.mainloop()

有人可以告诉我我做错了什么吗?非常感谢所有回复。谢谢。

这是一个典型的 Tkinter 错误。我不想详细说明,因为我也不完全理解为什么会发生这种情况,但它与垃圾收集器有关,而且它不考虑您为存储这些图像而创建的对象,例如正在使用中,所以它会删除它们;或类似的东西。

幸运的是,它有一个简单的解决方案:您可以创建一个内部列表变量,比如说 self._images 来存储您正在使用的每个图像,例如:

self._images = list()
(...)
self._images.append(logo)
(...)
self._images.append(banner)

或者,您可以为每个 canvas 实例分配一个属性 image(或 img,这并不重要),该属性存储它将要携带的图像实例.在您的代码中,它将类似于:

canvas_for_logo.image = logo
(...)
canvas_for_banner.image = banner

这样,您就可以避免垃圾收集器删除它不应该删除的内容,因为现在它承认该实例正在使用中。