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

Is it possible to set button state with dynamic name call using getattr and dictionary keys (Python 2.7, Tkinter)?

我正在构建一个 python Tkinter GUI 程序,其中包含按钮 enabled/disabled 取决于各种情况。 出于这个原因,我想动态地引用按钮而不是使用静态名称。我建立了一个全局字典,将按钮字符串描述符链接到一个布尔值,指示它们的期望状态(在小部件创建期间填充,并在整个程序中根据需要更改 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 的理解,这应该是等效的?

I would have thought .config() is an attribute of a widget object?

是的,config是widget对象的一个​​属性。但是,字符串 "config(state=DISABLED)" 不是小部件对象的属性。

如果您想调用存储在字典中的小部件的配置方法,您可以完全按照小部件是常规变量时的方式进行操作。以下示例将其分为两个步骤来说明这一点:

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