在Tkinter中获取绑定事件处理器

2 投票
3 回答
2790 浏览
提问于 2025-04-11 09:19

在Tkinter中,如果你把一个方法绑定到某个元素的事件上,是否有办法把这个方法找回来呢?

>>> root = Tkinter.Tk()
>>> frame = Tkinter.Frame(root, width=100, height=100)
>>> frame.bind('<Button-1>', lambda e: pprint('Click')) # function needed
>>> frame.pack()
>>> bound_event_method = frame.???

3 个回答

0

看起来好像不是这样……如果你需要这个,为什么不自己保存一下呢?或者用一个有名字的函数呢?

另外,你的代码写得不对:lambda 函数只能包含表达式,而不能有语句,所以 print 是不行的(在 Python 3.0 版本中,print() 会变成一个函数,那时候就可以用了)。

4

在Tcl/Tk中,做这个事情的方法非常简单:你只需要使用相同的绑定命令,但不加最后一个参数。

bind .b <Button-1> doSomething
puts "the function is [bind .b <Button-1>]"
=> the function is doSomething

在Tkinter中,你可以做类似的事情,但结果不太好用:

e1.bind("<Button-1>",doSomething)
e1.bind("<Button-1>")
=> 'if {"[-1208974516doSomething %# %b %f %h %k %s %t %w %x %y %A %E %K %N %W %T %X %Y %D]" == "break"} break\n'

显然,Tkinter在后台做了很多处理。一个解决办法是写一个小助手程序,帮你记住这些信息:

def bindWidget(widget,event,func=None):
    '''Set or retrieve the binding for an event on a widget'''

    if not widget.__dict__.has_key("bindings"): widget.bindings=dict()

    if func:
        widget.bind(event,func)
        widget.bindings[event] = func
    else:
        return(widget.bindings.setdefault(event,None))

你可以这样使用它:

e1=Entry()
print "before, binding for <Button-1>: %s" % bindWidget(e1,"<Button-1>")
bindWidget(e1,"<Button-1>",doSomething)
print " after, binding for <Button-1>: %s" % bindWidget(e1,"<Button-1>")

当我运行上面的代码时,我得到了:

before, binding for <Button-1>: None
 after, binding for <Button-1>: <function doSomething at 0xb7f2e79c>

最后要注意的是,我不太使用Tkinter,所以不太确定动态给一个控件实例添加属性会有什么影响。看起来是没什么问题,但如果有问题的话,你可以创建一个全局字典来跟踪这些绑定。

2

要在tk的C接口中实现这个功能,可以使用一个叫做 Get_GetCommandInfo 的函数。

这个函数会把关于命令的信息放在一个叫做 Tcl_CmdInfo 的结构体里,这个结构体是通过 infoPtr 指向的。

不过,这个函数在 _tkinter.c 文件中并没有被使用,而这个文件是Python通过 Tkinter.py 使用的tk绑定。

所以,你无法从tkinter中获取绑定的函数。你需要自己记住那个函数。

撰写回答