在帧之间切换时属性错误

时间:2018-04-04 12:58:51

标签: python user-interface tkinter attributes

使用Switch between two frames in tkinter中建议的方法,我试图在登录帧和寄存器帧之间切换。然而,在登录屏幕上按下注册按钮后调用showFrame(register)时,会发生属性错误:

(frame=self.frames[pageName]; AttributeError:'loginScreen' object has no 
attribute 'frames')



class mainActivity(Tk):
    def __init__(self, *args, **kwargs):
        Tk.__init__(self,*args,**kwargs)


        container=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 (loginScreen, register):
            frame = F(container, self)
            self.frames[F]=frame
            frame.grid(row=0, column=0, sticky="snew")

        self.showFrame(loginScreen)

    def showFrame(self, pageName):
        frame=self.frames[pageName]
        frame.tkraise()



#-------------------------------------------------

class loginScreen(Frame):
    def __init__(self, parent, controller):
        Frame.__init__(self, parent)
        self.controller=controller


        self.regBtn =Button(self, text="Register", command=self.regBtnClicked)
        self.regBtn.grid(row=2,column=1)

        self.grid()


    def regBtnClicked(self):
        mainActivity.showFrame(self, register)
        #send to register screen


#-------------------------------------------------

class register(Frame):
    def __init__(self, parent, controller):
        Frame.__init__(self, parent)
        self.controller=controller

        self.grid(row=0, column=0)



        self.cancelBtn = Button(self, text="Cancel",command=self.cancelBtnClicked)
        self.cancelBtn.grid(row=4, column=1)




    def cancelBtnClicked(self):
        #return to login screen
        mainActivity.showFrame(self, loginScreen)


app = mainActivity()
app.mainloop()

1 个答案:

答案 0 :(得分:1)

您的代码存在一些问题。首先,你错过了for F in (loginScreen, register): for循环的重要部分。

你需要:

page_name = F.__name__

这是用于为self.frames字典的键部分提供字符串名称的代码行。

所以不要这样做:

self.frames[F]=frame

请改为:

self.frames[page_name] = frame

尝试在排除故障时使用print语句。我只需要在发生错误之前添加print(self.frames),以便了解这里出了什么问题。

您还需要将self.showFrame(loginScreen)更改为self.showFrame("loginScreen")以及对showFrame()的任何其他调用,以反映相同的更改。

你遇到的另一个问题是这一行:

mainActivity.showFrame(self, loginScreen)

您需要在此处引用控制器,如下所示:

self.controller.showFrame("loginScreen")

您的帧类中不需要self.grid(row=0, column=0),因为这些已经在for循环中设置了。无需再做一次。

所有这些都可以看一下下面的代码:

from tkinter import *

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

        for F in (loginScreen, register):
            page_name = F.__name__
            frame = F(container, self)
            self.frames[page_name] = frame
            frame.grid(row=0, column=0, sticky="snew")

        print(self.frames)
        self.showFrame("loginScreen")

    def showFrame(self, pageName):
        frame=self.frames[pageName]
        frame.tkraise()
#-------------------------------------------------
class loginScreen(Frame):
    def __init__(self, parent, controller):
        Frame.__init__(self, parent)
        self.controller=controller
        self.regBtn = Button(self, text="Register", command=self.regBtnClicked)
        self.regBtn.grid(row=2,column=1)

    def regBtnClicked(self):
        self.controller.showFrame("register")
#-------------------------------------------------
class register(Frame):
    def __init__(self, parent, controller):
        Frame.__init__(self, parent)
        self.controller=controller
        self.cancelBtn = Button(self, text="Cancel",command=self.cancelBtnClicked)
        self.cancelBtn.grid(row=4, column=1)

    def cancelBtnClicked(self):
        self.controller.showFrame("loginScreen")


app = mainActivity()
app.mainloop()