Tkinter函数内调用问题:Command无法识别TK元素求助
Tkinter函数内控件无法被外部函数识别的解决方案
问题说明
将Tkinter界面代码封装到函数funcao内后,点击"disable"按钮触发switch函数时,报错NameError: name 'b1' is not defined。
正常运行的代码
from tkinter import * fenster = Tk() fenster.title("Window") def switch(): b1["state"] = DISABLED #--Buttons b1=Button(fenster, text="Button") b1.config(height = 5, width = 7) b1.grid(row=0, column=0) b2 = Button(text="disable", command=switch) b2.grid(row=0,column=1) fenster.mainloop()
报错的代码
from tkinter import * def switch(): b1["state"] = DISABLED def funcao(): fenster = Tk() fenster.title("Window") #--Buttons b1=Button(fenster, text="Button") b1.config(height = 5, width = 7) b1.grid(row=0, column=0) b2 = Button(text="disable", command=switch) b2.grid(row=0,column=1) fenster.mainloop() funcao()
原因分析
报错核心是变量作用域问题:
- 报错代码中,
b1是funcao函数内部的局部变量,仅在funcao的作用域内有效。 switch函数定义在全局作用域,无法访问funcao内部的局部变量,因此触发名称未定义错误。
解决方法
方案1:将switch函数定义在funcao内部
把switch放在funcao里,让它处于和b1相同的作用域,就能直接访问b1:
from tkinter import * def funcao(): # 把switch定义在funcao内部 def switch(): b1["state"] = DISABLED fenster = Tk() fenster.title("Window") b1=Button(fenster, text="Button") b1.config(height = 5, width = 7) b1.grid(row=0, column=0) b2 = Button(text="disable", command=switch) b2.grid(row=0,column=1) fenster.mainloop() funcao()
方案2:用lambda传递控件参数给switch
修改switch函数接收按钮参数,再通过lambda表达式把b1传给它,无需调整函数位置:
from tkinter import * # 让switch接收按钮作为参数 def switch(btn): btn["state"] = DISABLED def funcao(): fenster = Tk() fenster.title("Window") b1=Button(fenster, text="Button") b1.config(height = 5, width = 7) b1.grid(row=0, column=0) # 使用lambda将b1作为参数传入switch b2 = Button(text="disable", command=lambda: switch(b1)) b2.grid(row=0,column=1) fenster.mainloop() funcao()
方案3:声明b1为全局变量(不推荐)
通过global关键字把b1设为全局变量,让switch能访问它,但全局变量会增加代码维护难度,不建议在复杂界面中使用:
from tkinter import * def switch(): b1["state"] = DISABLED def funcao(): global b1 # 声明b1为全局变量 fenster = Tk() fenster.title("Window") b1=Button(fenster, text="Button") b1.config(height = 5, width = 7) b1.grid(row=0, column=0) b2 = Button(text="disable", command=switch) b2.grid(row=0,column=1) fenster.mainloop() funcao()
推荐方案
优先选择方案1或方案2,它们遵循局部作用域的设计原则,代码更清晰、更易维护。
内容的提问来源于stack exchange,提问作者Marcelo Cid Valerio
相关产品推荐
相关产品推荐

