如何在全局变量值改变时调用函数?

3

当全局变量 a 的值发生变化时,如何调用函数 change_label?使用 change_variable 我试图模拟变量的实际更改(变量在按钮单击时更改)。

from tkinter import *

a = 3

class Application(Frame):

    def __init__(self, master):
        Frame.__init__(self, master)
        self.master = master
        self.button = Button(self.master, text='Change Variable', command=self.change_variable)
        self.button.grid(row=0)
        self.label = Label(self.master, text='Test')
        self.label.grid(row=1)

    def change_label(self):
        self.label.config(bg='Red', fg='Yellow')

    def change_variable(self):
        global a
        a = 1

def main():
    root = Tk()
    Application(root)
    root.mainloop()

if __name__ == '__main__':
    main()

如果没有问题的话,你可以使用一个轻量级线程定期监控该值。 - undefined
好的,为什么不在所有改变a的地方直接调用change_label呢? - undefined
还有,看看这个:如何在值改变时触发函数? - undefined
4
为什么不使用对象属性而是使用全局变量,这样你就可以从 setter 中调用函数。 - undefined
4个回答

5
如果您使用Tkinter的特殊变量之一(如StringVar等),您可以添加一个“跟踪器”,每当该变量被设置或取消设置时,它将触发回调。例如:
class Application(Frame):

    def __init__(self, master):
        Frame.__init__(self, master)
        ...
        self.a = tk.IntVar(value=3)
        self.a.trace("w", self.change_label)
        ...

    def change_label(self, *args):
        self.label.config(bg='Red', fg='Yellow')

    def change_variable(self):
        self.a.set(1)

因此,每当您通过set方法设置self.a的值时,与trace绑定的函数将被调用。

使用该变量的任何小部件也将被更新。例如,将标签更改为以下内容:

self.label = tk.Label(self.master, textvariable=self.a)

当您点击按钮时,请注意标签的更改。
有关传递给跟踪函数的参数的描述,请参见Tkinter变量跟踪方法回调的参数是什么? 这些变量在此处有很好的描述:变量类(BooleanVar、DoubleVar、IntVar、StringVar)

0

如果你正在使用 Tk,这可能值得一看:Tk的“变量”类

如果这对你不起作用(因为你想存储自己的类型,或者类似的原因),Shiva的评论是正确的方法,如果你想存储多个变量,这可能是一个好主意:

class Storage(dict):
    def __getattribute__(self, name):
        return self[name]

    def __setattr__(self, name, value):
        print(name, value)  # react to the change of name
        self[name] = value

storage = Storage({a: 3, b: 2})

storage.a = 4
print(storage.a)

如果你不想在设置变量时触发一些你放在那里的代码,祝你好运。你也可以重写__setitem__,但你总是可以使用Storage变量作为第一个参数调用dict.__setitem__

0

试着运行这段代码,它会给你一个想法。

import tkinter
count = 5
def change_text():
        global count
        if count != 2:
                button.config(text='edit')

frame = tkinter.Frame(height=500,width=500)
button = tkinter.Button(frame,text='save',command=change_text)
button.place(x=0,y=0)
frame.pack()
frame.mainloop()

-1
The code was supposed be like this.
from tkinter import *

a = 3

class Application(Frame):

    def __init__(self, master):
        Frame.__init__(self, master)
        self.master = master
        self.button = Button(self.master, text='Change Variable', command=self.change_label)
        self.button.grid(row=0)
        self.label = Label(self.master, text='Test')
        self.label.grid(row=1)

    def change_label(self):
        global a
        a = 1
        if a != 3:
            self.label.config(bg='Red', fg='Yellow')

def main():
    root = Tk()
    Application(root)
    root.mainloop()
hope that is what you wanted.

你为什么添加了第二个答案?"代码应该是这样的"是什么意思?你知道你可以编辑你的原始回答吗? - undefined
你不需要change_variable方法,你仍然可以在一个方法中完成所有操作,就像已经做过的那样。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接