如何引用Python类__init__方法中创建的tkinter元素并更新界面内容
核心问题梳理
PageOne类__init__方法中创建的scroll_area、canvas等界面元素都是局部变量,未绑定到类实例,导致update_results方法无法访问这些元素。- 调用
update_results的方式错误,直接调用类方法而非已实例化的页面对象的方法,运行时无法匹配实例属性。 - 滚动区域未绑定尺寸变化事件,新增内容后滚动条无法适配内容高度,无法滚动查看超出范围的内容。
- 重复触发生成逻辑时,旧结果不会被清空,会和新内容叠加显示。
修正后完整代码
import tkinter as tk from tkinter import font as tkfont class SampleApp(tk.Tk): def __init__(self, *args, **kwargs): tk.Tk.__init__(self, *args, **kwargs) self.title_font = tkfont.Font(family='Helvetica', size=18, weight="bold", slant="italic") 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 = {} self.frames["StartPage"] = StartPage(parent=container, controller=self) self.frames["PageOne"] = PageOne(parent=container, controller=self) self.frames["StartPage"].grid(row=0, column=0, sticky="nsew") self.frames["PageOne"].grid(row=0, column=0, sticky="nsew") self.show_frame("StartPage") def show_frame(self, page_name): '''Show a frame for the given page name''' frame = self.frames[page_name] frame.tkraise() class StartPage(tk.Frame): def __init__(self, parent, controller): tk.Frame.__init__(self, parent) self.controller = controller label = tk.Label(self, text="This is the start page", font=controller.title_font) label.pack(side="top", fill="x", pady=10) button1 = tk.Button(self, text="Go to Page One", command=lambda: controller.show_frame("PageOne")) button1.pack() class stored_functions(): # 调整参数顺序,第一个参数接收传入的PageOne实例 def get_date(self, page_instance, entry): results = [] for x in range(1,21): answer = int(entry.strip()) * x results.append([x, answer]) # 用实例调用方法,而非直接调用类方法 page_instance.update_results(results) class PageOne(tk.Frame): def __init__(self, parent, controller): tk.Frame.__init__(self, parent) self.controller = controller title = tk.Label(self, text='Enter a Number') title.pack() self.text = tk.Text(self, font=controller.title_font, width=8, height=1) self.text.pack() button = tk.Button(self, text="Get Multiplication Table", command=lambda: stored_functions().get_date(self, entry=self.text.get('1.0', tk.END))) button.pack() divider = tk.Label(self, text='-------------------------------------------------') divider.pack() scrollable_frame = tk.Frame(self) scrollable_frame.config(width=50, height=100) scrollable_frame.pack() # 绑定到实例属性,供其他方法访问 self.canvas = tk.Canvas(scrollable_frame) self.scroll_area = tk.Frame(self.canvas) scroll_bar = tk.Scrollbar(scrollable_frame, orient='vertical', command=self.canvas.yview) self.canvas.config(width=250, height=100, yscrollcommand=scroll_bar.set) self.canvas.pack(side="left", fill="both", expand=True) self.canvas.create_window((4,4), window=self.scroll_area, anchor='nw') # 绑定内容尺寸变化事件,自动更新滚动范围 self.scroll_area.bind("<Configure>", lambda e: self.canvas.configure(scrollregion=self.canvas.bbox("all"))) header = tk.Label(self.scroll_area, text='Multiplication Table') header.grid(row=0, column=0, padx=(10, 10), pady=10) def update_results(self, results): # 先清空滚动区域旧内容 for widget in self.scroll_area.winfo_children(): widget.destroy() # 重新加表头 header = tk.Label(self.scroll_area, text='Multiplication Table') header.grid(row=0, column=0, padx=(10, 10), pady=10) entry = results[0][1] row=2 for i in results: statement = '{} multiplied by {} is {}.'.format(entry, i[0], i[1]) statement_text = tk.Text(self.scroll_area, height=1) statement_text.grid(row=row, column=0) statement_text.configure(state='normal') statement_text.insert(tk.END, statement) statement_text.configure(state='disabled') row += 1 if __name__ == "__main__": app = SampleApp() app.mainloop()
内容的提问来源于stack exchange,提问作者Lzypenguin
相关产品推荐
相关产品推荐

