You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Tkinter继承tk.Tk类时Button绑定自定义方法报错的问题求助(不使用Frame对象)

Fixing Tkinter AttributeError When Inheriting from tk.Tk (No Frame Needed)

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.Tk and call super().__init__(), your MyApplication instance gets linked to an underlying C-implemented _tkinter.tkapp object (the core Tcl/Tk runtime instance).
  • When you pass self.fun directly as the Button’s command, 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 your fun method, 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

火山引擎 最新活动