Python Tkinter菜单栏调用Page1类display方法报错排查
问题根源
- 错误的实例引用:你在
App类中把self.page1 = Page1赋值为类本身,而非Page1的实例。当通过菜单栏调用self.page1.display(self)时,实际是把App实例作为self传入Page1的display方法,此时方法内的self是App对象,自然没有body_frm属性。 - 方法调用方式错误:实例方法需要通过类的实例调用,直接通过类调用时必须手动传入实例对象,而你之前的调用方式都没正确绑定实例。
- 初始化顺序问题:
create_menu_frame在self.page1赋值前就被调用,导致菜单命令引用的对象未正确初始化。
修复步骤
1. 修正App类中页面实例的引用
在App的__init__方法中,先创建页面实例并存入self.frames,再将self.page1和self.page2指向实际的实例对象,同时调整create_menu_frame的调用顺序(放到实例创建之后):
def __init__(self): super().__init__() self.title('Method Test') self.geometry('500x300') # Create frame container container = tk.Frame(self) container.pack(side="top", fill="both", expand=True) container.grid_rowconfigure(0, weight=1) container.grid_columnconfigure(0, weight=1) # Create a dictionary of frames self.frames = {} # 先创建页面实例 for page_frame in (Page1, Page2): frame = page_frame(container, self) self.frames[page_frame] = frame frame.grid(row=0, column=0, sticky=tk.NSEW) # 将self.page1/self.page2指向实例,而非类 self.page1 = self.frames[Page1] self.page2 = self.frames[Page2] # 先完成实例创建,再创建菜单 self.create_menu_frame(self) # Switch to Page1 self.show_frame(Page1)
2. 修正菜单栏的命令调用
在create_menu_frame中,将Display菜单的命令改为直接调用实例的display方法:
file_menu.add_command( label='Display', command=self.page1.display)
或者用lambda(如果需要传递额外参数,但这里不需要):
file_menu.add_command( label='Display', command=lambda: self.page1.display())
3. 保持Page1类的display方法不变
Page1内部的display方法无需修改,因为self.body_frm是实例属性,应该绑定到实例而非类:
def display(self): label = tk.Label( self.body_frm, text='Display method works') label.grid(row=2, column=0, columnspan=2, padx=15, pady=5)
错误原因解析
command=self.page1.display原报错:因为之前self.page1是类而非实例,且create_menu_frame调用时self.page1未初始化,修正后self.page1是实例,实例方法会自动绑定self参数,调用正常。lambda: self.page1.display无报错但不执行:因为这只是引用了方法对象,没有实际调用,必须加()执行方法。lambda: self.page1.display()原报错:因为之前self.page1是类,调用类的实例方法需要传入实例参数,修正后self.page1是实例,调用时自动传入self,不再报错。
内容的提问来源于stack exchange,提问作者wmiller
相关产品推荐
相关产品推荐

