为什么我的图像没有出现在 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
这样,您就可以避免垃圾收集器删除它不应该删除的内容,因为现在它承认该实例正在使用中。
我正在尝试 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
这样,您就可以避免垃圾收集器删除它不应该删除的内容,因为现在它承认该实例正在使用中。