【问题标题】:AttributeError: 'Event' object has no attribute 'show_frame' in tkinter?AttributeError:“事件”对象在 tkinter 中没有属性“show_frame”?
【发布时间】:2020-12-07 12:46:31
【问题描述】:

这是完整的回溯消息

Exception in Tkinter callback Traceback (most recent call last): File "C:\Python\Python37\lib\tkinter\__init__.py", line 1702, in __call__ return self.func(*args) File "C:\test.py", line 61, in <lambda> canvas.tag_bind(obj1, '<1>', lambda event=None : controller.show_frame(Page1)) AttributeError: 'Event' object has no attribute 'show_frame

我想要什么?

当我应该点击图片时,它应该重定向到另一个框架,即 Page1。

我得到了什么?

当我单击图像以便从 StartPage(默认帧)移动到 Page1(下一帧)时,它显示错误“AttributeError: 'Event' object has no attribute 'show_frame'”

以下是我给出错误的代码。

from tkinter import *
from PIL import Image, ImageTk
   
class tkinterApp(Tk): 
      
    # __init__ function for class tkinterApp  
    def __init__(self, *args, **kwargs):  
          
        # __init__ function for class Tk 
        Tk.__init__(self, *args, **kwargs) 
          
        # creating a container 
        container = Frame(self)   
        container.pack(side = "top", fill = "both", expand = True)  
   
        # initializing frames to an empty array 
        self.frames = {}
        
        # iterating through a tuple consisting 
        # of the different page layouts 
        for F in (StartPage, Page1): 
   
            frame = F(container, self) 
   
            # initializing frame of that object from 
            # startpage, page1, page2 respectively with  
            # for loop 
            self.frames[F] = frame  
   
            frame.grid(row = 0, column = 0, sticky ="nsew")
        self.update()
        self.show_frame(StartPage)
   
    # to display the current frame passed as 
    # parameter 
    def show_frame(self, cont): # cont = page_name
        if cont not in self.frames:
            self.frames[cont] = cont(container, self)
        frame = self.frames[cont]
        frame.tkraise()
        frame.event_generate("<<ShowFrame>>")
   
# first window frame startpage 
   
class StartPage(Frame):
    def __init__(self, parent, controller):
        Frame.__init__(self, parent)
        self.bind("<<ShowFrame>>", self.myStartPage)

    def printcehck(self,event):
        print("hack")

    def myStartPage(self,controller):
        super(StartPage).__init__()
        print(controller)
        canvas = Canvas(self,width=300, height=300, bd=0, highlightthickness=0, relief='ridge')
        canvas.pack()

        self.background = PhotoImage(file="background.png")
        canvas.create_image(300,300,image=self.background, tags="B")

        self.character1 = PhotoImage(file="bg-e-butd.png")
        obj1 = canvas.create_image(50,50,image=self.character1, anchor=NW)
        canvas.tag_bind(obj1, '<1>', lambda event=None : controller.show_frame(self,Page1)) #error occurs here.
           
      
# second window frame page1  
class Page1(Frame): 
      
    def __init__(self, parent, controller): 
          
        Frame.__init__(self, parent)

        canvas = Canvas(self,width=300, height=300, bd=0, highlightthickness=0, relief='ridge')
        canvas.pack()

        self.background = PhotoImage(file="background.png")
        canvas.create_image(300,300,image=self.background, tags="B")

        self.character1 = PhotoImage(file="bg-e-butd.png")
        self.after(1000, lambda: (canvas.create_image(50,50,image=self.character1, anchor=NW)))

   
# Driver Code 
app = tkinterApp()
app.title("Title")
app.mainloop() 

谁能告诉我我在哪里做错了?我是使用 Tkinter 进行 GUI 开发的新手。

【问题讨论】:

  • 我看到了 2 个问题。您在几个地方缺少 self. 前缀,并且您在不需要时将 self 传递给 show_frame,因为这是在 tkinter 方法中自动传递的。

标签: python python-3.x tkinter tkinter-canvas tkinter-entry


【解决方案1】:

您需要将控制器定义为类属性。错误告诉您show_frame 不存在,因为该属性controller 不存在。

为了将你的框架正确地传递给其他类,你还需要在主类中将容器定义为类属性。

container 更改为self.container

在您的 StartPage 类和 Page1 类中,您需要将 self.controller = controller 添加到您的 init 中,以便您的其他类可以使用它。

我已经更新了你的代码(也删除了图像部分,因为我没有你的图像可以使用)所以我使用了一些标签。

如果您有任何问题,请告诉我。

import tkinter as tk
from PIL import Image, ImageTk


class tkinterApp(tk.Tk):
    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)
        self.title("Title")
        self.container = tk.Frame(self)
        self.container.pack(side="top", fill="both", expand=True)
        self.frames = {}

        for F in (StartPage, Page1):
            frame = F(self.container, self)
            self.frames[F] = frame

            frame.grid(row=0, column=0, sticky="nsew")
        self.update()
        self.show_frame(StartPage)

    def show_frame(self, cont):  # cont = page_name
        if cont not in self.frames:
            self.frames[cont] = cont(self.container, self)
        frame = self.frames[cont]
        frame.tkraise()
        frame.event_generate("<<ShowFrame>>")


class StartPage(tk.Frame):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        tk.Label(self, text='StartPage').pack()
        self.bind("<<ShowFrame>>", self.myStartPage)
        self.controller = controller

    def printcehck(self, event):
        print("hack")

    def myStartPage(self, controller):
        super(StartPage).__init__()
        print(controller)
        self.controller.show_frame(Page1)


class Page1(tk.Frame):
    def __init__(self, parent, controller):
        self.controller = controller
        tk.Frame.__init__(self, parent)
        tk.Label(self, text='Page1').pack()


if __name__ == '__main__':
    tkinterApp().mainloop()

【讨论】:

  • 非常感谢!使用self.controller = controller 解决了这个问题!
【解决方案2】:

事件回调的第一个参数(类方法的第二个)是Event对象,所以当使用下面的类方法作为事件回调时:

def myStartPage(self, controller):

controller 将是 Event 对象。这是你在使用时出现异常的原因:

canvas.tag_bind(obj1, '<1>', lambda event=None : controller.show_frame(self,Page1)) #error occurs here.

要解决此问题,您需要更改为以下行:

self.bind("<<ShowFrame>>", self.myStartPage)

到:

self.bind("<<ShowFrame>>", lambda e: self.myStartPage(controller))

请注意,您还必须删除以下行中的额外参数 self

canvas.tag_bind(obj1, '<1>', lambda event=None : controller.show_frame(self,Page1))

即:

canvas.tag_bind(obj1, '<1>', lambda event=None : controller.show_frame(Page1))

myStartPage() 中的以下行也不是必需的:

super(StartPage).__init__()

【讨论】:

    猜你喜欢
    • 2019-12-17
    • 2019-08-25
    • 1970-01-01
    • 2023-02-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多