Python 为什么我的图像没有出现在tkinter画布上

Python 为什么我的图像没有出现在tkinter画布上,python,tkinter,tkinter-canvas,Python,Tkinter,Tkinter Canvas,我正试图把这个UI作为学校评估的一部分,从一个刺激中制作出来。我尝试导入页面顶部框架上提供的学校徽标和横幅,并将图像放在画布上,但尚未取得任何结果。当我运行代码时,图片根本不会加载。我使用的代码如下所示: from tkinter import * import random import time import sqlite3 from tkinter import simpledialog from tkinter import messagebox from tkcalendar impo

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

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()
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()
我决定制作一个单独的文件来测试图像是否可以在没有类的情况下加载,它做到了。代码如下:

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()
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.\u images
,存储您正在使用的每个图像,例如:

self._images = list()
(...)
self._images.append(logo)
(...)
self._images.append(banner)
或者,您可以为每个画布实例指定一个属性
image
(或者
img
,这并不重要),该属性存储它将携带的图像实例。在您的代码中,它将类似于:

canvas_for_logo.image = logo
(...)
canvas_for_banner.image = banner
通过这种方式,您可以避免垃圾收集器删除不应该删除的内容,因为现在它确认此实例正在使用。

谢谢:),它现在工作得很好:)