2013-05-04 95 views
3

我正在使用Python 2.7.4和新的Tkinter,並且我堅持使用下面的代碼。 我生成了一個事件「測試」,並設置了「數據」選項與一個字符串,但從事件中檢索它時發生錯誤。[Python/Tkinter]我如何獲取在函數「event_generate」中設置的數據的值

錯誤 - > 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支持「數據」選項嗎?謝謝!

回答

7

不,不幸的是它沒有。 Tcl解釋器將其識別爲有效的選項,但它是Event類中未包含的其中一個缺失選項,如warp。您可以查看Tkinter source code的第1188行以查看其他缺失的選項。

+0

感謝您的幫助! – vicd 2013-05-04 03:17:00

+0

但是,我檢查了字段「Tkinter.TkVersion」和「Tkinter.TclVersion」,它們都是8.5。它似乎只是部分支持一些選項參考http://www.tcl.tk/man/tcl8.4/TkCmd/event.htm我很抱歉聽到Python現在不支持這些缺失的選項,我一晃一晃某人在python.org上提交了一個問題作爲功能請求,希望他們能解決它http://bugs.python.org/issue3405 – vicd 2013-05-04 03:19:21

+0

@vicd不客氣。有一個補丁,但它已於2008年發佈。我已將自己添加到問題列表中,所以如果有任何消息,我會通知您。 – 2013-05-04 10:48:06

2

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

注意:似乎有一個競賽條件,阻止事件被捕獲後過小的延遲。

相關問題