如何创建通用方法来更改不同类属性的True / False值?

问题描述

我正在使用窗口的类对象创建GUI。该窗口有很多按钮可以打开和关闭不同的设置面板。我班上的一个简单例子是:

import tkinter as tk 

class MyWindow(object):
    def __init__(self):
        # flags which are used to draw settings panels if True,and not draw if False
        self.settings1 = True
        self.settings2 = True 

        # create frames for each panel of settings 
        self.frame1 = tk.LabelFrame(window,text = "First panel")
        self.frame2 = tk.LabelFrame(window,text = "Second panel")
        self.frame1.grid()
        self.frame2.grid() 

        # add button widget to each frame 
        self.button1 = tk.Button(self.frame1,text = "ON",bg = "green",command = lambda: self.changeButtonState(self.button1,self.settings1))
        self.button2 = tk.Button(self.frame2,command = lambda: self.changeButtonState(self.button2,self.settings2))
        self.button1.grid()
        self.button2.grid()

    def changeButtonState(self,button,flag):
        if button["text"] == "ON":
            button["text"] = "OFF"
            button["bg"] = "red"
            
            # change the state of the given flag
            flag = False 
        else: 
            button["text"] = "ON"
            button["bg"] = "green"
            
            # change state of flag
            flag = True 

        print("Settings 1: ",self.settings1,"\nSettings 2: ",self.settings2)

# create the window 
window = tk.Tk()
x = MyWindow()
window.mainloop()

按钮的颜色和文本变化很好, ,但是单击按钮时self.settings1self.settings2的值保持不变 。我不明白为什么,因为函数中的flag应该是类属性之一,但是它像对待新变量一样对待它!

如何创建一个通用函数来更改传递给它的类属性的状态?

解决方法

更改参数的值不会更改用于设置的值。但是没有真正的理由将self.settings1传递给函数。作为一种方法,它已经可以访问self,因此可以访问 any 设置。首先,将设置存储在容器中,而不是单独命名的属性中:

def __init__(self):
    self.settings = {'setting1': True,'setting2': True}
    ...

然后,将设置的名称传递给对self.changeButtonState的调用:

    ...
    self.button1 = tk.Button(self.frame1,text = "ON",bg = "green",command = lambda: self.changeButtonState(self.button1,"settings1"))
    ...

最后,使用名称为您的dict设置编制索引:

def changeButtonState(self,button,flag):
    if button["text"] == "ON":
        button["text"] = "OFF"
        button["bg"] = "red"
        
        # change the state of the given flag
        self.settings[flag] = False 
    else: 
        button["text"] = "ON"
        button["bg"] = "green"
        
        # change state of flag
        self.settings[flag] = True 

    print("Settings 1: ",self.settings['setting1'],"\nSettings 2: ",self.settings['setting2'])
,

self.settings1self.settings2不变的原因是,在changeButtonState函数调用期间没有更改它们。相反,您要做的是将值传递给函数。我认为您认为以下行:

flag = True

应更改self.settings1变量。但是,由于在Python中如何处理变量,情况并非如此。这是an article,详细介绍了该主题。