Reputation: 2859
I'm a bit confused about information provided concerning events in Tcl/Tk.
Is it possible in Tcl/Tk to determine which element of a scrollbar was under the mouse for a ButtonPress
event, such as arrow1 or slider?
Also, is it possible to bind an event to a particular element of a scrollbar, such as v_scroll.arrow1
?
I realize that scrollbars have built in events for scrolling but was experimenting to determine how events work overall and information provided about them.
Is it possible to determine which widget or widget element upon which any mouse event took place, such as binding to a parent window and querying upon which child an event was initiated?
It appears that Python has event.widget
but I'm not using Python but Tcl.
I've been reading the Dr. Ousterhout book and the documentation but, unfortunately, haven't been able to find it.
I can bind to the scrollbar, of course, and determine which mouse button was pressed but not which element of the scrollbar was under the mouse at that time. Using winfo
returns the scrollbar .v_scroll
only and not the element under the mouse.
Thank you.
ttk::scrollbar .v_scroll -orient vertical -command ".canvas yview"
bind .v_scroll <ButtonPress> { puts "Pressed button %b at [winfo containing %X %Y]" }
Upvotes: 0
Views: 239
Reputation: 137627
Is it possible in Tcl/Tk to determine which element of a scrollbar was under the mouse for a ButtonPress event, such as arrow1 or slider?
That's exactly what the scrollbar's identify
method does:
set what [$scrollbar identify $x $y]
Also, is it possible to bind an event to a particular element of a scrollbar, such as v_scroll.arrow1?
No. Indeed, it's not usually a good idea to bind anything to scrollbars yourself; the class bindings do what you need and are best left alone. Bindings on the widget(s) that the scrollbar scrolls are better.
Is it possible to determine which widget or widget element upon which any mouse event took place, such as binding to a parent window and querying upon which child an event was initiated?
Yes. Events have a %W
substitution that is the widget that is their target (NB: only canvas
and text
widgets really allow sub-widget bindings) and are typically delivered to both the widget and its toplevel (mostly useful for key accelerators). You can tell additional widgets to be targets for events delivered to a widget by adjusting the delivery widget's bindtags
to list additional targets, but you should be careful as that can be very confusing if a widget isn't prepared for it. (In my experience, only toplevels, frames and canvases are good targets, mostly because they've got very few default bindings of their own via class bindings.) Lots of applications never use bindtags
at all, and many more don't put extra widgets in the binding tags; it's intensely subtle. Sometimes, generating a virtual event instead is a neater way forward, but whether that's true for you depends a lot on both the bigger picture and the details of what you're trying to do.
You can also use winfo containing
within an event binding to discover what widget is under a particular global coordinate (%X %Y
, not %x %y
). You don't normally do that, except when you really need it; it's vital if you're doing drag-and-drop (as user interaction events during a mouse button press are always delivered to the widget where the mouse press started). It's possible to modify this with grabs, but grabs are a great way to break your application (or even your login session if you're using global grabs!) so extreme care is needed.
Widget sub-component identification is always a matter for the widget to decide. It's conventionally a matter for the identify
method of the widget, but that's only convention; canvases and text widgets use different mechanisms. And not all widgets even have sub-components; classic button
s don't, for example (but ttk::button
s do). Typically, such identification is used by binding scripts to decide what to do next, and isn't used anywhere else.
In summary, event management is complicated. Virtually all of the complication is necessary in some cases, and there's a lot going on behind the curtain.
Upvotes: 1