与Tkinter跟踪相关的回调函数有哪些限制?

时间:2012-03-26 02:30:40

标签: python user-interface tkinter

我试图弄清楚如何实现一个回调函数,它做的事情比打印输出更有意义。我相当缺乏经验,所以我不确定回调函数应该如何或可以用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回调函数?如果没有,我该如何使这个工作?

3 个答案:

答案 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()