2

子要素をクリックしても親要素に反映されないのはなぜですか?

from tkinter import *

root = Tk()

def handler(event):
    print('clicked at', event.x, event.y)

frame = Frame(root, width=100, height=100)
label = Label(frame, text="Label")
frame.bind('<Button-1>', handler)
frame.pack()
label.pack(side=TOP)

root.mainloop()

それを実行すると、ラベルをクリックしてもハンドラーが起動しません。イベントはデフォルトで親に伝達されることを理解しました。それを望まない場合は、「break」を返す必要があります。

4

2 に答える 2

5

イベントが親に伝播するという最初の理解は間違っています。彼らはしない。

確かに、トップレベルまたはルート ウィンドウの直接の子孫であるウィジェットには、エッジ ケースがあります。そこでも、それらが親に伝播しているわけではなく、バインド タグで定義されているように他のバインディングによって処理されており、デフォルトでは、すべてのウィジェットにバインド タグの 1 つとしてトップレベル ウィンドウがあります。

どこでも機能するようにバインディングを設定したい場合は、bind_allメソッドを使用できます。各ウィジェットにはデフォルトで「すべて」の bindtag があるためです。もう 1 つのオプションは、(bindtagsメソッドを使用して) 複数のウィジェットに同じ bindtag を与えてから、. でその bindtag にバインドすることですbind_class。どちらを選択するかは、何を達成しようとしているかによって異なります。

bindtags は非常に強力です。おそらく、他のツールキットのバインディング メカニズムよりも強力です。たとえば、イベントを伝播させる必要がある場合は、すべてのウィジェットの bindtags を調整してその祖先をすべて含めることで実現できます。しかし、私の経験では、そのような悪ふざけが必要になることはめったにありません。

于 2012-09-10T18:36:06.013 に答える
0

あなたは間違っています。 "break"そのイベントが、クリックされたウィジェットの他のハンドラーに伝播されないようにします。

つまり、アクションをにlabelバインドしてから、別のアクションを最初のボタンにバインドするとlabel、両方のコールバックが呼び出されます(呼び出される最初のボタンから戻った場合を除く"break")。

ただし、回避策はわかりません...(BryanOakleyが表示されるのを待つ必要があるかもしれません;)

于 2012-09-10T17:06:43.667 に答える