Вы можете попробовать что-то вроде этого:
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)
Если вам нужны аргументы, просто используйте лямбда-функцию.В свете этого (и принятого ответа, который я недавно изучил более подробно), вот более сложная версия с комментариями, дополнительными функциями и примерами:
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()
- это еще одна альтернатива, которая вызывает остановку вызывающей функции без остановки графического интерфейса пользователя до тех пор, пока не изменится указанная вами переменная.Есть и другие похожие методы.