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 は "data" オプションをサポートしていますか? ありがとう!

4

2 に答える 2

3

Tkinter は、event_generate のデータ フィールドを適切に処理しません。

これは、このフィールドを読み取ることができる Tkinter (実際には Tcl...) のプライベート API を使用したスニペットです。この関数はリテラルでのみ機能し、通常はリテラルを含む辞書にデータを渡します。

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

注: after の遅延が小さすぎると、イベントがキャッチされないという競合状態があるようです。

于 2014-04-21T10:52:50.827 に答える