Python Tkinter 如何识别并配置触发公共命令的被点击按钮
核心实现方案
要在公共回调函数中识别触发点击的按钮,不需要为每个按钮单独编写事件,有两种可直接落地的实现方式,适配你当前9宫格按钮的场景。
方法1:通过lambda闭包传递按钮实例
这是最贴合tkinter command 属性使用逻辑的方案,核心是在绑定回调时,把当前按钮的实例作为参数传给公共函数,同时规避Python闭包的晚绑定问题。
- 先把公共更新函数改造为接收按钮参数:
def update(btn): # 直接对传入的按钮实例做状态修改即可 btn.config(fg=white)
- 给每个按钮绑定回调时,用lambda把当前创建的按钮固定为函数入参:
# 单按钮绑定示例 button11 = tkinter.Button(window, text="●", width=3, height=1, font=('나눔스퀘어 bold', '20'), bg=grey, fg=grey) # 注意这里必须用默认参数b=button11固定当前按钮值,否则会触发闭包晚绑定,所有按钮点击都会触发最后创建的按钮逻辑 button11.config(command=lambda b=button11: update(b))
注意:如果直接写command=lambda: update(button11),运行时所有按钮的回调都会引用最终的button11变量值,出现点击所有按钮都触发同一个按钮更新的问题,必须用默认参数在定义lambda时锁定当前按钮实例。
方法2:通过统一事件绑定获取触发源
这种方式不需要在每个按钮的command属性里单独写绑定逻辑,只需要给所有按钮统一绑定鼠标点击事件,利用事件对象自动传递触发组件的特性实现识别。
- 改造公共更新函数,直接接收tkinter传递的事件对象:
def update(event): # event.widget 就是触发本次点击事件的按钮实例 event.widget.config(fg=white)
- 统一给窗口内所有按钮绑定点击事件,不需要逐个在按钮定义时写绑定:
# 遍历窗口下所有子组件,给按钮类组件统一绑定左键点击事件 for widget in window.winfo_children(): if isinstance(widget, tkinter.Button): widget.bind("<Button-1>", update)
额外优化建议
你当前手动逐个创建9个按钮、逐个布局的写法重复度极高,完全可以用循环批量生成,减少冗余代码:
# 用二维列表存储所有按钮,方便后续按坐标做井字棋逻辑判断 button_container = [] for row_idx in range(3): row_buttons = [] for col_idx in range(3): btn = tkinter.Button( window, text="●", width=3, height=1, font=('나눔스퀘어 bold', '20'), bg=grey, fg=grey ) btn.grid(row=row_idx, column=col_idx) row_buttons.append(btn) button_container.append(row_buttons)
内容的提问来源于stack exchange,提问作者Jaehyeon Kim
相关产品推荐
相关产品推荐

