我试图弄清楚如何实现一个回调函数,它做的事情比打印输出更有意义。我相当缺乏经验,所以我不确定回调函数应该如何或可以用Python(或任何其他语言)实现。
考虑以下Python代码:
from Tkinter import *
def callbackfunc(*args):
print "Hello World!"
class App:
def __init__(self, master):
frame = Frame(master)
frame.pack()
optionvalue = IntVar(master)
optionvalue.set(2)
optionvalue.trace("w", callbackfunc)
self.optionmenu = OptionMenu(master, optionvalue, 1, 2, 3, 4)
self.optionmenu.pack()
我正在尝试实现一个OptionMenu(一个Tkinter小部件),这样当它的选择值改变时,我的回调函数会做一些有意义的事情 - 更具体地说,它会改变一个全局变量值,在程序的其他地方定义。如上所述,它只是打印输出(虽然成功)。
我无法弄清楚如何将参数传递给我的回调函数。我不希望这个特殊的回调函数返回任何东西;但是,我很好奇我将如何使我的回调函数返回一些东西,以及如何实现我的程序的其余部分,以便它可以利用那些返回的结果,无论那些可能是什么。我是否试图以一种不打算实现的方式实现Python回调函数?如果没有,我该如何使这个工作?
答案 0 :(得分:4)
通过“将参数传递给我的回调函数”,你有点不清楚。你已经这样做了!例如:
from Tkinter import *
def callbackfunc(*args, **kwargs):
print args, kwargs
print "Hello World!"
class App(object):
def __init__(self, master):
frame = Frame(master)
frame.pack()
optionvalue = IntVar(master)
optionvalue.set(2)
optionvalue.trace("w", callbackfunc)
self.optionmenu = OptionMenu(master, optionvalue, 1, 2, 3, 4)
self.optionmenu.pack()
root = Tk()
app = App(root)
root.mainloop()
跑步时......
$ python foo.py
('PY_VAR0', '', 'w') {}
Hello World!
所以你看,当Tkinter调用你的回调时,它会将参数传递给它。如果你想做除打印之外的其他事情,你可以通过传递方法而不是函数将它们存储在某种状态。
from Tkinter import *
class App(object):
def __init__(self, master):
frame = Frame(master)
frame.pack()
optionvalue = IntVar(master)
optionvalue.set(2)
optionvalue.trace("w", self.callbackfunc)
self.optionmenu = OptionMenu(master, optionvalue, 1, 2, 3, 4)
self.optionmenu.pack()
self.state = []
def callbackfunc(self, *args):
self.state.append(args)
print self.state
root = Tk()
app = App(root)
root.mainloop()
跑步时......
$ python foo.py
[('PY_VAR0', '', 'w')]
[('PY_VAR0', '', 'w'), ('PY_VAR0', '', 'w')]
[('PY_VAR0', '', 'w'), ('PY_VAR0', '', 'w'), ('PY_VAR0', '', 'w')]
此外,您可能希望访问optionvalue
的值。您可以保存对它的引用:
from Tkinter import *
class App(object):
def __init__(self, master):
frame = Frame(master)
frame.pack()
self.optionvalue = IntVar(master)
self.optionvalue.set(2)
self.optionvalue.trace("w", self.callbackfunc)
self.optionmenu = OptionMenu(master, self.optionvalue, 1, 2, 3, 4)
self.optionmenu.pack()
self.state = []
def callbackfunc(self, *args):
self.state.append(args)
print self.state
print self.optionvalue.get()
root = Tk()
app = App(root)
root.mainloop()
跑步时......
$ python foo.py
[('PY_VAR0', '', 'w')]
1
[('PY_VAR0', '', 'w'), ('PY_VAR0', '', 'w')]
2
[('PY_VAR0', '', 'w'), ('PY_VAR0', '', 'w'), ('PY_VAR0', '', 'w')]
3
您也可以root.getvar(name)
使用name = 'PY_VAR0'
(传递给回调的第一个arg),如noob oddy所示。
答案 1 :(得分:2)
如果你想发送额外的参数 - 或者只是你选择的参数 - 你可以使用lambda。有些人发现lambda令人困惑,但它可以成为一个强大的工具。
根据需要定义你的回调:
def callbackfunc(message=None):
print message
使用lambda接受Tkinter传入的参数和关键字参数,以获取您想要发送的任何其他参数,然后使用您想要的任何参数调用回调。例如:
optionvalue.trace("w", lambda name, index, op,
message="hello, world": callbackfunc(message))
你也可以使用functools.partial以一种可以说是更容易理解的语法来做同样的事情。
答案 2 :(得分:1)
from Tkinter import *
def callbackfunc(name, index, mode):
print root.getvar(name)
class App:
def __init__(self, master):
frame = Frame(master)
frame.pack()
optionvalue = IntVar(master)
optionvalue.set(2)
optionvalue.trace("w", callbackfunc)
self.optionmenu = OptionMenu(master, optionvalue, 1, 2, 3, 4)
self.optionmenu.pack()
root = Tk()
app = App(root)
root.mainloop()