为何报错AttributeError: type object 'App' has no attribute 'tk'?
问题:AttributeError: type object 'App' has no attribute 'tk'
运行以下代码时会抛出错误AttributeError: type object 'App' has no attribute 'tk',仅在App类内部调用entryField函数时触发该错误,类外部调用则正常。疑惑继承tk.Tk的App类为何无tk属性,能否结合类式与函数式组件?
代码示例
import tkinter as tk from tkinter import ttk def entryField(parent): frame = ttk.Frame(master = parent) return frame class App(tk.Tk): def __init__(self): #main setup super().__init__() #widgets entryField(App).pack() self.mainloop() App()
回溯信息
Traceback (most recent call last): File "C:\Users\[REDACTED]\[REDACTED]\[REDACTED]\[REDACTED]\example.py", line 22, in <module> App() File "C:\Users\[REDACTED]\[REDACTED]\[REDACTED]\[REDACTED]\example.py", line 17, in __init__entryField(App).pack() ^^^^^^^^^^^^^^^ File "C:\Users\[REDACTED]\[REDACTED]\[REDACTED]\[REDACTED]\example.py", line 6, in entryField frame = ttk.Frame(master = parent) ^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.11_3.11.1264.0_x64__qbz5n2kfra8p0\Lib\tkinter\ttk.py", line 710, in __init__Widget.__init__(self, master, "ttk::frame", kw) File "C:\ProgramFiles\WindowsApps\PythonSoftwareFoundation.Python.3.11_3.11.1264.0_x64__qbz5n2kfra8p0\Lib\tkinter\ttk.py", line 527, in __init__tkinter.Widget.__init__(self, master, widgetname, kw=kw) File "C:\ProgramFiles\WindowsApps\PythonSoftwareFoundation.Python.3.11_3.11.1264.0_x64__qbz5n2kfra8p0\Lib\tkinter\__init__.py", line 2622, in __init__self._setup(master, cnf) File "C:\ProgramFiles\WindowsApps\PythonSoftwareFoundation.Python.3.11_3.11.1264.0_x64__qbz5n2kfra8p0\Lib\tkinter\__init__.py", line 2591, in _setupself.tk = master.tk ^^^^^^^^^ AttributeError: type object 'App' has no attribute 'tk'
问题分析与解决
错误原因
你调用entryField(App)时,传入的是App类本身,而不是类的实例对象。tk属性是tk.Tk被实例化后才会生成的实例属性,类本身并没有这个属性,所以ttk.Frame初始化时找不到父容器的tk属性,直接报错。
修正方案
把entryField(App)改成entryField(self),self是当前App类的实例,已经通过super().__init__()完成了父类tk.Tk的初始化,具备tk属性,可以作为父容器传递给entryField函数。
修正后的代码:
import tkinter as tk from tkinter import ttk def entryField(parent): frame = ttk.Frame(master=parent) # 可以添加输入框测试显示效果 ttk.Entry(frame).pack(padx=15, pady=15) return frame class App(tk.Tk): def __init__(self): super().__init__() # 传入实例self而非类App entryField(self).pack() self.mainloop() App()
关于类式与函数式组件结合
完全可以结合使用类式和函数式组件:
- 函数式组件(比如entryField)可以用来封装独立的UI模块,接收父容器实例作为参数,返回组装好的组件,便于复用。
- 类式组件(比如App)用来管理整个应用的生命周期、全局状态和布局结构。
这种组合方式能让代码结构更清晰,模块化程度更高,是Tkinter开发中常用的写法。
内容的提问来源于stack exchange,提问作者Nifty_Biscuit
相关产品推荐
相关产品推荐

