是否可以使用getattr和字典键(Python2.7,Tkinter)通过动态名称调用设置按钮状态



我正在构建一个包含按钮的python Tkinter GUI程序,这些按钮将根据各种情况启用/禁用。出于这个原因,我想动态地引用按钮,而不是使用静态名称。我构建了一个全局字典,它将按钮字符串描述符链接到一个布尔值,该布尔值指示它们所需的状态(在小部件创建过程中填充,并在整个程序中根据需要更改dict值(,以及一个函数中的另一个字典,该函数将相同的字符串描述符链接至按钮对象名称。

由于我希望动态更改按钮状态,所以对象名称不是硬编码的,相反,我尝试将getattr与使用上述字典函数返回对象名称的函数调用一起使用:

class WApplication(Frame):

buttonStates={}
...

def buttonDisable(self):
for i in self.buttonStates:
#self.Load_Manifest.config(state=DISABLED)   #This line works (i.e., visibly disables the 'Load Manifest' button)
#print(i+".config(state=DISABLED)")          #Output: Load_Manifest.config(state=DISABLED)
getattr(self.ObjectDictionary(i),"config(state=DISABLED)")   #AttributeError: Button instance has no attribute 'config(state=DISABLED)'

def buttonEnable(self):   #Similar error encountered as above when debugging this function
for i in self.buttonStates:
if self.buttonStates[i]==True:
getattr(self.ObjectDictionary(i),"config(state=NORMAL)")

...
def ObjectDictionary(self,string):
"Function that maps dictionary widget keys to their object titles and returns the mapped object title"
switcher={
"Load_Manifest":self.Load_Manifest,
"Update_Manifest":self.Update_Manifest,
"Fresh_Manifest":self.Fresh_Manifest,
"Manifest_Details":self.Manifest_Details
}
return switcher.get(string)

...

def createWidgets(self):
self.QUIT = Button(self.master)
self.QUIT["text"] = "QUIT"
self.QUIT["fg"]   = "red"
self.QUIT["command"] =  self.quit
self.QUIT.place(x=710,y=10,height=50,width=100)

self.Load_Manifest=Button(self.master)
self.Load_Manifest["text"]="Load Manifest"
self.Load_Manifest["command"]=self.LoadManifestButton
self.Load_Manifest.config(state=NORMAL)
self.Load_Manifest.place(x=10,y=10,height=50,width=110)
self.buttonStates["Load_Manifest"]=True
self.buttonActions["Load_Manifest"]=False

self.Update_Manifest=Button(self.master)
self.Update_Manifest["text"]="Update Manifest"
self.Update_Manifest["command"]=self.UpdateManifestButton
self.Update_Manifest.config(state=DISABLED)
self.Update_Manifest.place(x=130,y=10,height=50,width=120)
self.buttonStates["Update_Manifest"]=False
self.buttonActions["Update_Manifest"]=False

self.Fresh_Manifest=Button(self.master)
self.Fresh_Manifest["text"]="Create New Manifest"
self.Fresh_Manifest["command"]=self.FreshManifestWindowButton
self.Fresh_Manifest.config(state=NORMAL)
self.Fresh_Manifest.place(x=260,y=10,height=50,width=150)
self.buttonStates["Fresh_Manifest"]=True
self.buttonActions["Fresh_Manifest"]=False

...

self.Manifest_Details=Button(self.master)
self.Manifest_Details["text"]="Details"
self.Manifest_Details["command"]=self.ManifestDetailsButton
self.Manifest_Details.config(state=DISABLED)
self.Manifest_Details.place(x=10,y=790,height=50,width=100)
self.buttonStates["Manifest_Details"]=False
self.buttonActions["Manifest_Details"]=False

...

buttonDisable和buttonEnable函数在按下按钮期间运行的其他函数中的程序其他位置调用。我可以坚持使用硬编码的小部件名称,并在我的buttonEnable函数中放入大量if语句,因为目前可能只有四个按钮,但我计划扩展程序,添加更多额外的按钮,并且我希望在操作过程中禁用所有按钮,以避免用户在程序繁忙时进入,因此需要动态调用。

在getattr(self.ObjectDictionary(i(;config(state=DISABLED("(出现错误:

AttributeError: Button instance has no attribute 'config(state=DISABLED)'

但我想.config((是一个小部件对象的属性吗?和下面的硬编码替换行self。Load_Manifest.config(state=DISABLED(按预期工作,根据我对getattr的理解,哪个应该是等效的?

我本以为.config((是小部件对象的属性?

是的,config是小部件对象的属性。然而,字符串"config(state=DISABLED)"不是小部件对象的属性。

如果你想调用存储在字典中的小部件的configure方法,你可以像调用小部件是一个正则变量一样。以下示例将其分解为两个步骤来说明这一点:

widget = ObjectDictionary(i)
widget.configure(state=DISABLED)

最新更新