Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Listbox Binding (this s/b simple)

Status
Not open for further replies.

cptk

Technical User
Mar 18, 2003
305
US
All I want to do is when I single click (i.e. select a new item) on an element within a listbox, I'd like to send the element value to another procedure.

I'm not having trouble with binding per se, but my problem is that I can only get it to work using <Double-ButtonPress-1> binding, which is what I don't want to do. I want to be able to go to each element in the listbox and send that value to a proc without double-clicking. When I try bind types like ButtonPress or KeyPress, it will send the value to my proc, but it's always the previous value, not the current selection ... what am I missing here (duh?)?
 
I found my solution, but I'm can't explain it well enough ...anyone care to elaborate on the bindtag cmd
and the ordering mechanism?

SOLUTION:
Only thing I changed is that I added a bindtags cmd that changes the order:

bindtags .listbox {Listbox .listbox . all}

Note: I'm also still using the following bind:
bind .listbox <ButtonPress-1> {do my cmds}

 
My mistake ...
My new bind cmd is ...

bind .listbox <ButtonRelease> {do my cmds}
 
You certainly found a workable solution. In case you're still a bit hazy on how the bindtags command works, you can take a quick look at my replies in Thread287-211083. Given that additional background, you can probably figure out what's happening in your case...

Most widget functionality is actually coded in Tcl, rather than C. This makes it easier to change the behavior of widgets if desired. The behavior of "select a listbox item when the user clicks it with the mouse" is an example of such Tcl-coded behavior. It's implemented via [tt]<ButtonPress-1>[/tt], [tt]<B1-Motion>[/tt], and [tt]<ButtonRelease-1>[/tt] bindings on the Listbox bindtag. (The behavior is more complex than it sounds at first, because the listbox supports 4 different selection modes.) So, because the default bindtag path fires your widget-specific binding first, it sees the "old" selection. Then, the Listbox class binding fires, which performs the select action, as you observed. Your bindtag solution works fine, because it forces the Listbox class binding to fire first, handling the selection action, and then fires your widget-specific binding.

However, a better solution probably would be to use the [tt]<<ListboxSelect>>[/tt] virtual event (introduced in Tcl/Tk 8.1), which is generated by a listbox whenever its selection changes. The event fires after the selection has changed, so the binding action can access the new selection. Here's an example of using it:

Code:
proc ListboxChanged {w} {
    puts -nonewline "Listbox $w selection is now: "
    foreach index [$w curselection] {
        puts -nonewline "[$w get $index]"
    }
    puts ""
}

bind .lbox <<ListboxSelect>> {ListboxChanged %W}

- Ken Jones, President, ken@avia-training.com
Avia Training and Consulting, 866-TCL-HELP (866-825-4357) US Toll free
415-643-8692 Voice
415-643-8697 Fax
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top