Tkinter多页面切换代码运行报错:__init__()方法出现TypeError无法解决
问题根因与修复方案
- 你对
pack()/grid()方法的返回值认知错误:这两个布局方法执行后返回None,你写的box=Frame(self).pack(fill=BOTH,expand=1)会导致box变量实际为None,后续把None作为父容器传入子Frame,直接触发参数类型错误。必须先创建组件实例赋值给变量,再单独调用布局方法。 - 自定义
login/register类的初始化参数匹配错误:你定义的两个页面类__init__要求传入parent(父容器)、controller(控制器也就是主窗口)两个必传参数,但你在window类中实例化页面时根本没有调用自定义类,也没有传入要求的参数,参数数量不匹配触发报错。 - 父类初始化重复调用且参数错误:自定义页面类中同时写了
Frame.__init__(self, parent)和super().__init__(**kwargs),属于重复初始化,且super调用没有传入parent参数,参数不匹配。 - 类名与实例变量名冲突:你将自定义类名和实例变量都命名为
login/register,后续按钮回调中直接写类名而非实例对象,调用逻辑完全错误。 - Frame实例化参数顺序错误:ttk.Frame的首个参数只能是父容器,你写的
Frame(box,self)传入了两个父容器参数,不符合API要求。
修复后完整代码
from tkinter import * from tkinter.ttk import * class Window(Tk): def __init__(self, **kwargs): super().__init__(**kwargs) # 先创建容器,再单独调用pack self.box = Frame(self) self.box.pack(fill=BOTH, expand=1) # 实例化自定义页面类,传入要求的父容器和controller参数 self.login_page = Login(self.box, self) self.login_page.pack(fill=BOTH, expand=1) self.register_page = Register(self.box, self) self.register_page.pack(fill=BOTH, expand=1) # 初始显示登录页 self.fup(self.login_page) def fup(self, f): f.tkraise() # 类名遵循首字母大写规范,避免和实例变量冲突 class Login(Frame): def __init__(self, parent, controller, **kwargs): # 去掉重复初始化,只保留super调用并传入parent参数 super().__init__(parent, **kwargs) Label(self, text='Login').grid(row=0, column=3, pady=3) # 回调传入注册页实例 Button(self, text='Signup', command=lambda: controller.fup(controller.register_page)).grid(row=4, column=0) class Register(Frame): def __init__(self, parent, controller, **kwargs): super().__init__(parent, **kwargs) Label(self, text='Register').grid(row=0, column=3, pady=3) # 回调传入登录页实例 Button(self, text='<<', command=lambda: controller.fup(controller.login_page)).grid(row=0, column=0) if __name__ == "__main__": win = Window() win.mainloop()
内容的提问来源于stack exchange,提问作者kaleintesh
相关产品推荐
相关产品推荐

