Gary
Gary

Reputation: 2859

Binding events to widget elements and information provided about an event?

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

Answers (1)

Donal Fellows
Donal Fellows

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 buttons don't, for example (but ttk::buttons 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

Related Questions