Tkinter继承tk.Tk类时Button绑定自定义方法报错的问题求助(不使用Frame对象)
Great question—since you’re focused on understanding Tkinter’s mechanics without using a Frame (even though you know this isn’t the optimal GUI structure), let’s break down why this error happens and fix it step by step.
Why the Error Occurs
The error AttributeError: '_tkinter.tkapp' object has no attribute 'fun' stems from how Tkinter handles the main window (tk.Tk) and method bindings:
- When you inherit from
tk.Tkand callsuper().__init__(), yourMyApplicationinstance gets linked to an underlying C-implemented_tkinter.tkappobject (the core Tcl/Tk runtime instance). - When you pass
self.fundirectly as the Button’scommand, Tkinter tries to look for this method on the underlying tkapp object instead of your custom Python class instance. Since the tkapp object doesn’t have yourfunmethod, you get the error.
Fix 1: Use a Lambda to Wrap the Method Call
The simplest fix is to use a lambda expression to explicitly call your instance’s fun method. This creates a small wrapper that captures your MyApplication instance and ensures the method is called on it, not the tkapp object:
import tkinter as tk class MyApplication(tk.Tk): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.title('Programma') self.geometry('500x400') # Wrap the method call in a lambda self.button = tk.Button(self, text='Execute', command=lambda: self.fun()) self.button.grid(row=0, column=4, stick=tk.W) def fun(self): print('Hello') app = MyApplication() app.mainloop()
Fix 2: Use functools.partial for Explicit Binding
If you prefer a more formal approach (useful if you need to pass arguments to fun later), use functools.partial to bind the method directly to your Python instance:
First import partial at the top:
from functools import partial import tkinter as tk
Then update the Button creation line:
self.button = tk.Button(self, text='Execute', command=partial(self.fun))
partial creates a callable that explicitly ties your self.fun method to your MyApplication instance, avoiding the tkapp object lookup issue.
Key Tkinter Mechanics to Understand
Unlike Frame (a pure Python widget wrapper), the main tk.Tk class is tightly integrated with the low-level Tcl/Tk runtime. When creating widgets after calling super().__init__(), Tkinter’s default binding logic can sometimes mix up the Python instance with the underlying tkapp object. Using a lambda or partial creates a clear layer that ensures the method call targets your custom class’s implementation, not the runtime’s internal object.
内容的提问来源于stack exchange,提问作者Andrea




