Tkinter扩展Button类时如何正确设置参数及解决属性报错?
错误核心原因及修复方案
1. 构造方法调用错误(直接导致你看到的报错)
你抛出AttributeError: type object 'Button' has no attribute 'tk'的根因是TabButton类的父类初始化调用写法错误,同时没用对传入的参数:
# 错误写法 super().__init__(Button)
super().__init__()需要传入父类Button构造要求的父容器、配置参数,你定义的*args和**kwargs就是用来接收实例化时传入的所有位置、关键字参数(比如你写的side_frame、command参数),直接传给父类构造即可,修改后:
class TabButton(Button): def __init__(self, *args, **kwargs): # 把接收的所有参数传给父类Button完成初始化 super().__init__(*args, **kwargs) self['bg'] = '#a1a1a1' self['font'] = ('Agency', 24) def display_items(self, tab): pass # 后续放开查询时建议先校验tab是否在预设的表名白名单中,避免SQL注入
2. 循环生成按钮的逻辑错误
你现有循环代码有三个问题:
row=0写在循环内部,每次循环都会重置行号,所有按钮会堆在第一行display_items是实例方法,不能直接用类名TabButton调用,需要用实例调用- 直接在lambda里用
tab会触发闭包延迟绑定问题,所有按钮点击都会传入最后一个表名
修改后的代码:
tabs = { 'Table1': '', 'Table2': '', 'Table3': '', } # 行号初始化放在循环外部 row = 0 for tab in tabs: # 用默认参数t=tab绑定当前循环的表名,解决闭包问题 tabs[tab] = TabButton(side_frame, command=lambda t=tab: tabs[t].display_items(t)) tabs[tab].grid(row=row, column=0, pady=3) row += 1
可选优化
你可以把每个按钮对应的表名存在实例属性里,不用每次调用display_items都传参,修改后类代码更简洁:
class TabButton(Button): # 新增tab参数接收对应表名 def __init__(self, tab, *args, **kwargs): super().__init__(*args, **kwargs) self.tab = tab self['bg'] = '#a1a1a1' self['font'] = ('Agency', 24) def display_items(self): # 直接用self.tab即可,无需传参 print(f"加载表内容:{self.tab}")
对应的实例化代码调整为:
tabs[tab] = TabButton(tab, side_frame, command=lambda t=tab: tabs[t].display_items())
内容的提问来源于stack exchange,提问作者Jordan Regan
相关产品推荐
相关产品推荐

