你可以试试这样的:
class Variable:
def __init__(self, v):
self.v=v
self.command=None
def set(self, v):
self.v=v
if self.command!=None:
self.command()
def get(self):
return self.v
def trace(self, command):
self.command=command
x=Variable(0)
def money():
amount="{:.2f}".format(x.get())
print("You have $"+amount+".")
x.trace(money)
x.set(5.55)
x.set(15.14)
如果您需要参数,只需使用 lambda 函数。鉴于此(以及我最近更彻底地研究过的公认答案),这里有一个更复杂的版本,包含 cmets、更多功能和示例:
class Variable: #This is a class for the variable you want to bind something to
def __init__(self, v):
self.v=v
self.commands=[]
def set(self, v): #Set the variable's value and call any bound functions
self.v=v
for x in self.commands:
x()
def get(self): #Get the variable's value
return self.v
def trace(self, *commands): #Bind one or more functions to the variable
for x in commands:
if x in self.commands:
raise ValueError("You can’t add the same command object twice. If you need to, use another lambda function that calls the same function with the same parameters.")
self.commands.extend(commands)
def untrace(self, *commands): #Unbind one or more functions from the variable
for x in commands:
if x not in self.commands:
raise ValueError(str(x)+" is not a traced command.")
for x in commands:
if x in self.commands:
self.commands.remove(x)
def clear_traces(self): #Removes all functions bound to the variable
self.commands.clear()
x=Variable(0) #Make the variable, starting with a value of 0
def money(name): #Define the method to bind
amount="{:.2f}".format(x.get())
print(name+" has $"+amount+".")
sam=lambda : money("Sam") #We're making a new method to bind that calls the old one with the argument "Sam"
sally=lambda : money("Sally") #Another one (Sally and Sam will always have the same amount of money while they are both bound to the variable.)
#Bind them both to the value (not that this is practical, but we're doing both for demonstration)
x.trace(sam)
x.trace(sally)
#Set the value
x.set(5.55)
#Unbind the sam lambda function and set the value again
x.untrace(sam)
x.set(15.14)
"""
This prints the following:
> Sam has $5.55.
> Sally has $5.55.
> Sally has $15.14.
"""
另类
不管怎样,你也可以使用Tkinter自带的内置功能,比如DoubleVar.trace()或者someWidget.wait_variable()。
trace() 方法允许您将方法绑定到 StringVar、IntVar、FloatVar、DoubleVar、BooleanVar 或此类变量。这是一个完整的 Python 3.x 示例:
from tkinter import *
tk=Tk()
tk.withdraw()
d=DoubleVar(master=tk, value=0)
def my_event_handler(*args):
amount="{:.2f}".format(d.get())
print("$"+amount)
d.trace(mode="w", callback=my_event_handler)
d.set(5.55)
d.set(15.12)
"""
This prints the following:
> You have $5.55.
> You have $15.12.
"""
您可能希望在程序结束时销毁 Tk 对象。但是,在我的示例中,如果没有它,它似乎可以正常退出。
wait_variable() 是另一种替代方法,它会导致调用函数停止而不停止 GUI,直到您指定的变量发生更改。还有其他类似的方法。