7

我正在使用 Python 2.7.4 和 Tkinter 的新手,我坚持使用以下代码。我生成了一个事件“test”并使用字符串设置了“data”选项,但是从事件中检索它时发生了错误。

错误-> AttributeError:事件实例没有属性“数据”

from Tkinter import *

def handle_it(event):
    # print "event handler"
    print event.data

root = Tk()
root.after(1, lambda: root.event_generate('<<test>>', data="hi there"))
root.bind('<<test>>', handle_it)
root.mainloop()

我找不到这个案例的相关 Python 文档,所以我参考了 tcl 文档如下 http://www.tcl.tk/man/tcl8.5/TkCmd/event.htm#M14

Python 2.7 的 TKinter 是否支持“数据”选项?谢谢!

4

2 回答 2

9

不,不幸的是它没有。Tcl 解释器将其识别为有效选项,但它是未包含在 Event 类中的缺失选项之一,例如warp. 您可以查看Tkinter 源代码的第 1188 行以查看其余缺少的选项。

于 2013-05-04T02:35:10.633 回答
3

Tkinter 没有正确处理 event_generate 的数据字段。

这是一个使用 Tkinter 的私有 API(实际上是 Tcl ...)的片段,它允许读取该字段。此函数仅适用于文字,我通常将数据传递给带有文字的字典。

from Tkinter import *

def handle_it(event):
    # print "event handler"
    print event.data

def bind_event_data(widget, sequence, func, add = None):
    def _substitute(*args):
        e = lambda: None #simplest object with __dict__
        e.data = eval(args[0])
        e.widget = widget
        return (e,)

    funcid = widget._register(func, _substitute, needcleanup=1)
    cmd = '{0}if {{"[{1} %d]" == "break"}} break\n'.format('+' if add else '', funcid)
    widget.tk.call('bind', widget._w, sequence, cmd)

root = Tk()

# unfortunately, does not work with my snippet (the data argument is eval-ed)
# you can adapt it to handle raw string.
root.after(100, lambda : root.event_generate('<<test>>', data="hi there"))
# works, but definitely looks too hacky
root.after(100, lambda : root.event_generate('<<test>>', data="'hi there'"))
# the way I typically use it
root.after(100, lambda : root.event_generate('<<test>>', data={"content": "hi there"}))

#should be:
#  root.bind('<<test>>', handle_it)
bind_event_data (root, '<<test>>', handle_it)

root.mainloop()

注意:似乎有一个竞争条件阻止事件在之后的太小延迟中被捕获。

于 2014-04-21T10:52:50.827 回答