【问题标题】:Tkinter OOP "PyImage1" doesn't exist, errorTkinter OOP“PyImage1”不存在,错误
【发布时间】:2018-12-07 12:53:54
【问题描述】:

我不确定我的代码有什么问题,但每当我尝试运行它时,我都会收到以下错误:

File "L:\Year 12 and 13\Computer Science\NEA\30.11.18\GUI TKINTER\no cont.py", line 80, in __init__
    button3 = tk.Button(self, command=lambda: controller.MusicClick(), image = musicPic, text="Music", fg="Orange",font="none 20").place(x=30, y=640)
  File "C:\Program Files (x86)\Python36-32\lib\tkinter\__init__.py", line 2363, in __init__
    Widget.__init__(self, master, 'button', cnf, kw)
  File "C:\Program Files (x86)\Python36-32\lib\tkinter\__init__.py", line 2293, in __init__
    (widgetName, self._w) + extra + self._options(cnf))
_tkinter.TclError: image "pyimage1" doesn't exist

我知道这一定是代码的 OOP 方面的问题,因为我有一个非常相似的非 OOP 版本的代码,它可以完美运行,没有错误:

#Importing GUI
from tkinter import *

#Window Properties
window = Tk()
window.geometry('1280x720')
window.configure(background="blue")

#Declaring
SFXisMuted = False
MusicisMuted = False

#Title
Label (window, text="Connect 4 - Made by Luke Petrocochino", bg="blue", fg="white", font="Comic_Sans 40 bold").place(x=150,y=150)

#Pictures
musicPic = PhotoImage(file="musicalnoteresize.gif")
musicPicMUTED =PhotoImage(file="musicalnoteresizeMUTED.gif")
SFXPic = PhotoImage(file="SFXresize.gif")
SFXPicMUTED = PhotoImage(file="SFXresizeMUTED.gif")

#Command Sub Routines

def SFXClick():
    global SFXisMuted
    if SFXisMuted == False:
        button4 = Button(command=SFXClick, text="SFX", image=SFXPicMUTED, fg="Orange",font="none 20").place(x=110, y=640)
        SFXisMuted = True
    else:
        button4 = Button(command=SFXClick, text="SFX", image=SFXPic, fg="Orange",font="none 20").place(x=110, y=640)
        SFXisMuted = False

def MusicClick():
    global MusicisMuted
    if MusicisMuted == False:
        button3 = Button(command=MusicClick, text="Music",image=musicPicMUTED, fg="Orange",font="none 20").place(x=30, y=640)
        MusicisMuted = True
    else:
        button3 = Button(command=MusicClick, text="Music",image=musicPic, fg="Orange",font="none 20").place(x=30, y=640)
        MusicisMuted = False

def CloseWindow():
    window.destroy()
    exit()

#Buttons
button1 = Button(text ="Play!", font="none 60", fg= "Green").place(x=550, y=280)

button2 = Button(command=CloseWindow, text="Exit ",font="none 20", fg="Red").place(x=1175, y=640)

button3 = Button(command=MusicClick, text="Music",image=musicPic, fg="Orange",font="none 20").place(x=30, y=640)

button4 = Button(command=SFXClick, text="SFX", image=SFXPic, fg="Orange",font="none 20").place(x=110, y=640)



#End
window.mainloop()

这是我用 OOP 制作的版本,它给了我错误:(我的所有图像文件都在保存我的代码的目录中。)

#Importing GUI

import tkinter as tk
app = tk.Tk()
LARGE_FONT= ("Verdana", 12)


class Connect4(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 = {}

        SFXisMuted = False
        MusicisMuted = False

        for F in (StartPage, PageOne, PageTwo):

            frame = F(container, self)

            self.frames[F] = frame

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

        self.show_frame(StartPage)

    def show_frame(self, cont):
        frame = self.frames[cont]
        frame.tkraise()

    def SFXClick(self):
        global SFXPic
        global SFXisMuted
        if SFXisMuted == False:
            button4 = Button(command=SFXClick, text="SFX", image=SFXPicMUTED, fg="Orange",font="none 20").place(x=110, y=640)
            SFXisMuted = True
        else:
            button4 = Button(command=SFXClick, text="SFX", image=SFXPic, fg="Orange",font="none 20").place(x=110, y=640)
            SFXisMuted = False
        print("it works")

    def MusicClick(self):
        global MusicisMuted
        global musicPic
        if MusicisMuted == False:
            button3 = Button(command=lambda: controller.MusicClick, text="Music",image=musicPicMUTED, fg="Orange",font="none 20").place(x=30, y=640)
            MusicisMuted = True
        else:
            button3 = Button(command=MusicClick, text="Music",image=musicPic, fg="Orange",font="none 20").place(x=30, y=640)
            MusicisMuted = False

    def CloseWindow(self):
        Connect4.destroy(self)
        exit()

class StartPage(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self,parent)
        label = tk.Label(self, text="Start Page", font=LARGE_FONT)
        musicPic = tk.PhotoImage(file="musicalnoteresize.gif")
        SFXPic = tk.PhotoImage(file="SFXresize.gif")

        label = tk.Label(self, text="Connect 4 - Made by Luke Petrocochino", bg="blue", fg="white", font="Comic_Sans 40 bold").place(x=150,y=150)

        button1 = tk.Button(text ="Play!", font="none 60", fg= "Green").place(x=550, y=280)

        button2 = tk.Button(self, command=lambda: controller.CloseWindow(),  text="Exit ",font="none 20", fg="Red").place(x=1175, y=640)

        button3 = tk.Button(self, command=lambda: controller.MusicClick(), image = musicPic, text="Music", fg="Orange",font="none 20").place(x=30, y=640)

        button4 = tk.Button(self, command=lambda: controller.SFXClick(), image = SFXPic, text="SFX", fg="Orange",font="none 20").place(x=110, y=640)

        button3.image = musicPic
        button4.image = SFXPic

class PageOne(tk.Frame):

def __init__(self, parent, controller):
    tk.Frame.__init__(self, parent)
    label = tk.Label(self, text="Page One", font=LARGE_FONT)
    label.pack(pady=10,padx=10)

    buttonNav = tk.Button(self, text="Back to Home",
                          command=lambda: controller.show_frame(StartPage))
    buttonNav.pack()


class PageTwo(tk.Frame):

def __init__(self, parent, controller):
    tk.Frame.__init__(self, parent)
    label = tk.Label(self, text="Page Two", font=LARGE_FONT)
    label.pack(pady=10,padx=10)

    buttonNav = tk.Button(self, text="Back to Home",
                          command=lambda: controller.show_frame(StartPage))
    buttonNav.pack()

    button2 = tk.Button(self, text="Page One",
                          command=lambda: controller.show_frame(PageOne))
    button2.pack()



app = Connect4()
app.geometry('1280x720')
app.configure(background="blue")
app.mainloop()

我是 tkinter OOP 的新手,如果这是一个非常简单的错误,我深表歉意。

【问题讨论】:

标签: python oop user-interface tkinter


【解决方案1】:

这很难找到。通过将按钮传递给place() 创建按钮时,您犯了一个常见错误。 Place 将返回None,这意味着您将没有对按钮的引用。

button3 = tk.Button(self, command=lambda: controller.MusicClick(),
                    image = musicPic, text="Music",
                    fg="Orange", font="none 20").place(x=30, y=640)

而是先创建按钮并将其放置在之后:

button3 = tk.Button(self, command=lambda: controller.MusicClick(),
                    image = musicPic, text="Music",
                    fg="Orange", font="none 20")
button3.place(x=30, y=640)

否则您将无法将图像保存到按钮:

button3.image = musicPic

那么你在创建根窗口时也犯了一个不寻常的错误:

app = tk.Tk()

并将您的应用程序命名为相同的名称:

app = Connect4()

这有一个效果,但我不明白为什么会这样,但效果是按钮找不到您传递给它的图像。如果您只是删除第一个app = tk.Tk(),一切正常。

还有;在Connect4 中的函数MusicClick() 中,您正在创建几个变量global。这对我来说似乎很奇怪,因为 OOP 的好处之一是您不需要全局变量。我会改为让它们成为实例变量。

【讨论】:

  • 虽然place 返回None 是正确的,但这不是问题所在。堆栈跟踪是在创建按钮时发生的,而不是在稍后尝试访问它时发生的。
  • 我不明白这是什么意思。您能否提供一个链接,以更全面地解释或描述其工作原理。
  • 我不知道该怎么解释。问题在于小部件的创建,而不是稍后尝试修改它。换句话说,错误发生在 .place 被调用之前。
  • 是的,我同意。但是我对确切的问题感到困惑;是不是多个Tk() 实例搞砸了按钮的创建?
  • 感谢程序现在运行。但是,我的功能仍然存在问题。您说我不需要全局变量,而应该将它们设为实例变量。那么我应该在哪里声明这些变量,在调用函数时我必须通过括号传递它们吗?
猜你喜欢
  • 2014-06-07
  • 2022-07-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-12
相关资源
最近更新 更多