Reputation: 142
suppose I have the following Widget hierarchy:
set Frame [frame .f -relief flat]
set Button [button .f.b1]
In addition, if I would like to emulate a button
widget's -overrelief
by doing the following:
# When the mouse hovers over Frame
bind $Frame <Enter> "$Frame configure -relief groove"
# When it exits
bind $Frame <Leave> "$Frame configure -relief flat"
The problem becomes that $Button
somehow breaks this "chain of propagation", i.e. the <Enter>
event does not reach $Frame
. Is there a remedy or is this inherent Tk behavior?
EDIT:
The above example works if the (Mouse) pointer touches the outer border and then triggers <Enter>
event, but the issue remains, the following modification to the code illustrates this best:
#When the pointer is inside the frame widget, print x,y (as relative to the widget)
bind .f <Motion> {puts {%x %y}}
puts
gets called only when the pointer is on the edges of the frame, not inside the frame itself.
Upvotes: 1
Views: 139
Reputation: 4813
I cannot reproduce the issue you claim. When my mouse pointer enters the button (even coming from another window that partly covers the Tk GUI so the pointer never touches the frame), I get an <Enter> event on both the frame and the button.
Using your example code, the relief change is not visible because a frame has a default borderwidth of 0. So you would need to specify a borderwidth of 2 or so.
Here's a complete script that works for me as you seem to want:
set Frame [frame .f -relief flat -borderwidth 2]
set Button [button .f.b1]
grid $Frame
grid $Button
# When the mouse hovers over Frame
bind $Frame <Enter> [list $Frame configure -relief groove]
# When it exits
bind $Frame <Leave> [list $Frame configure -relief flat]
The <Motion> event indeed doesn't get reported to the frame. If you want that to happen too, you can add the frame to the bindtags of the button:
bindtags $Button [linsert [bindtags $Button] 1 $Frame]
That will make any event on the button to also trigger the frame bindings, unless specifically prevented by button bindings.
With this in place, the <Enter> and <Leave> events of the frame actually trigger twice when entering the button directly. Once because of the event on the frame iteself, and another time due to the bindtags of the button.
Upvotes: 1