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

How can I create a general method to change the True/False value of different class attributes?

我正在为 window 使用 class 对象创建 GUI。这个 window 有很多按钮可以打开和关闭不同的设置面板。我的 class 的一个简单例子是这样的:

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, text = "ON", bg = "green", 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 应该是 class 属性之一,但它把它当作一个新变量!

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

更改参数值不会更改用于设置参数的值。但是没有真正的理由将 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 详细介绍了该主题。