How to do stuff when a variable's value is modified?

后端 未结 1 1663
北海茫月
北海茫月 2020-12-22 12:47

How to do stuff when a variable\'s value is modified?

try:                        # In order to be able to import tkinter for
    import tkinter as tk    # e         


        
相关标签:
1条回答
  • 2020-12-22 12:58

    One way would be to make use of Variable classes(BooleanVar, DoubleVar, IntVar, StringVar, Variable), and their trace_add method. Which allows to call a method when the value the instance holds is modified.

    try:                        # In order to be able to import tkinter for
        import tkinter as tk    # either in python 2 or in python 3
    except ImportError:
        import Tkinter as tk
    
    
    def do_stuff(*_):   # trace_add implicitly passes 3 internal arguments
        demo['text'] = var.get() # to obtain the value var holds
    
    
    if __name__ == '__main__':
        root = tk.Tk()
        var = tk.StringVar(value="Value")
        #var = tk.BooleanVar(value=True)
        #var = tk.DoubleVar(value=2.78)
        #var = tk.IntVar(value=0)
        #var = tk.Variable(value=["Value", True, 2.78, 0])
        demo = tk.Label(root, text=var.get())
        demo.pack()
        var.trace_add('write', do_stuff)    # call do_stuff when var is set
        var.set("New Value")    # to replace the value var holds
        #var.set(False)
        #var.set(3.14)
        #var.set(42)
        #var.set(["New Value", False, 3.14, 42])
        tk.mainloop()
    

    Also further note that, while not always practical, some widgets have variable options(variable, textvariable, listvariable) that allows the value they hold to be in sync with that of a Variable class object. Below example makes use of that:

    try:                        # In order to be able to import tkinter for
        import tkinter as tk    # either in python 2 or in python 3
    except ImportError:
        import Tkinter as tk
    
    
    if __name__ == '__main__':
        root = tk.Tk()
        var = tk.StringVar(value="Value")
        demo = tk.Label(root, textvariable=var)
        demo.pack()
        var.set("New Value")    # label is in sync right-away
        tk.mainloop()
    

    Another way would be to make use of attribute assignment magic method(__setattr__) of an object, when working with classes.

    For example the demo label will be updated each time self.string attribute is modified:

    try:                        # In order to be able to import tkinter for
        import tkinter as tk    # either in python 2 or in python 3
    except ImportError:
        import Tkinter as tk
    
    
    class MyLabel(tk.Label):
        def __init__(self, master, var="", *args, **kwargs):
            tk.Label.__init__(self, master, *args, **kwargs)
            self.var = var
    
    
        def __setattr__(self, name, value):
            self.__dict__[name] = value
            if name == 'var':
                self.do_stuff()
    
    
        def do_stuff(self):
            self['text'] = self.var
    
    
    if __name__ == '__main__':
        root = tk.Tk()
        demo = MyLabel(root, "Value")
        demo.pack()
        demo.var = "New Value"
        tk.mainloop()
    
    0 讨论(0)
提交回复
热议问题