Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python ';类别';对象没有属性';ImageTk';_Python_Python 3.x_Tkinter_Tkinter Canvas - Fatal编程技术网

Python ';类别';对象没有属性';ImageTk';

Python ';类别';对象没有属性';ImageTk';,python,python-3.x,tkinter,tkinter-canvas,Python,Python 3.x,Tkinter,Tkinter Canvas,我正在努力在按钮上获取图像,而不是用于UI目的的文本,我没有在UI上处理图像的经验,因此我正在寻找一些指导,当我传递图像时,我得到了错误: AttributeError:“打开模板”对象没有属性“ImageTk” 也许有人能解释一下我在课堂上传递ImageTk时遗漏了什么 from tkinter import * from tkinter import messagebox from PIL import ImageTk, Image import datetime import tkinte

我正在努力在按钮上获取图像,而不是用于UI目的的文本,我没有在UI上处理图像的经验,因此我正在寻找一些指导,当我传递图像时,我得到了错误:

AttributeError:“打开模板”对象没有属性“ImageTk”

也许有人能解释一下我在课堂上传递ImageTk时遗漏了什么

from tkinter import *
from tkinter import messagebox
from PIL import ImageTk, Image
import datetime
import tkinter as tk
import webbrowser
import pytz
import openpyxl

class Main_App(tk.Tk):

    def __init__(self,*args,**kwargs):

        tk.Tk.__init__(self,*args,**kwargs)

        container = tk.Frame(self)
        container.pack(side="top",fill="both",expand=True)
        container.grid_rowconfigure(0, weight = 1)
        container.grid_columnconfigure(0, weight = 1)

        self.frames= {}

        for F in (test1,test2):

            frame = F(container, self)

            self.frames[F]=frame

            frame.grid (row=0, column = 0, sticky="nsew")

        self.show_frame(test1)

    def show_frame(self,cont):

        frame = self.frames[cont]
        frame.tkraise()

def SetMenu(self,parent,controller):

    Button1= tk.Button(self,relief='flat',command=lambda:controller.show_frame(test1))
    Button1.grid(column=0,row=0,sticky="nsew")
    Button1.config(image=self.ImageTk.PhotoImage(file ="image.gif"))


class test1(tk.Frame):

    def __init__(self, parent, controller):

        tk.Frame.__init__(self,parent)
        SetMenu(self,parent, controller)

class test2(tk.Frame):

    def __init__(self, parent, controller):

        tk.Frame.__init__(self,parent)
        SetMenu(self,parent, controller)

app=Main_App()
app.mainloop()
所以,我找到了一种方法让它发挥作用。那是

Button1=Button(self,bg="white",relief='flat',command=lambda:controller.show_frame(test1))
Button1.grid(column=0,row=0,sticky="nsew")
self.ph_im4 = ImageTk.PhotoImage(file = "image.gif")
Button1.config(image=self.ph_im4)

但是这种情况超出了我想要做的目的,因此我需要能够在没有变量的情况下加载图像,或者我需要创建500个变量来手动加载和映射每个图像

为什么要将self添加到ImageTk

Button1.config(image=ImageTk.PhotoImage(file ="image.gif"))
如果需要防止垃圾收集器:

def SetMenu(self,parent,controller):

    self.button1_image=ImageTk.PhotoImage(file ="image.gif")
    Button1= tk.Button(self,relief='flat',command=lambda:controller.show_frame(test1))
    Button1.grid(column=0,row=0,sticky="nsew")
    Button1.config(image=self.button1_image)
    Button1.image=self.button1_image


为什么要将self添加到ImageTk

Button1.config(image=ImageTk.PhotoImage(file ="image.gif"))
如果需要防止垃圾收集器:

def SetMenu(self,parent,controller):

    self.button1_image=ImageTk.PhotoImage(file ="image.gif")
    Button1= tk.Button(self,relief='flat',command=lambda:controller.show_frame(test1))
    Button1.grid(column=0,row=0,sticky="nsew")
    Button1.config(image=self.button1_image)
    Button1.image=self.button1_image


始终将完整的错误消息(从单词“Traceback”开始)作为文本(而不是屏幕截图)进行讨论(不是评论)。还有其他有用的信息。请始终将完整的错误消息(从单词“Traceback”开始)作为文本(而不是屏幕截图)进行讨论(而不是评论)。还有其他有用的信息。如果我不将其作为self传递,它不会加载图像,它会变成一个白色的正方形,我不会从sublime text tho中得到错误。您的解决方案将在
SetMenu()函数中创建
ImageTk.PhotoImage
的本地实例,该实例将在
SetMenu()之后被垃圾收集
已完成。@Josh Rodriguez您在帖子中提到的解决方案就是其中之一。但我不明白你为什么说它不适用于你的设计。@acw1668这里的想法是有一个构造函数,将图像分配给按钮。如果我使用相同的变量将其分配给另一个按钮,第一个按钮将删除图像,并且按钮将成为bg颜色的正方形,然后您可以将图像引用附加到分配的按钮。例如,如果名为
btn
的按钮变量,则
btn.image=image
。如果我不将其作为self传递,则它不会加载图像,它会变成一个白色正方形,升华文本tho不会出错。您的解决方案将在
SetMenu()
函数中创建
ImageTk.PhotoImage
的本地实例,而实例将在
SetMenu()
完成后被垃圾收集。@Josh Rodriguez您在文章中提到的解决方案就是其中之一。但我不明白你为什么说它不适用于你的设计。@acw1668这里的想法是有一个构造函数,将图像分配给按钮。如果我使用相同的变量将其分配给另一个按钮,第一个按钮将删除图像,并且按钮将成为bg颜色的正方形,然后您可以将图像引用附加到分配的按钮。例如,如果按钮变量名为
btn
,则
btn.image=image