14 May 2003 - Eric Boudaillier
Arjen Markus asked Support for quick positioning by typing first letter in Tk features request. After playing with this feature in Windows Explorer, I have written a little command which do this to place in binding.
# ---------------------------------------------------------------------- # ListboxQuickSelect -- # # This command implements quick positioning inside a listbox # with key press. Each key pressed are buffered for the search. # # Typical usage is through binding: # bind $listbox <KeyPress> "ListboxQuickSelect %W %A" # # ---------------------------------------------------------------------- proc ListboxQuickSelect {listbox key} { upvar 0 ::ListboxQuickSelect:$listbox data if {[string equal $key ""]} { # %A substitute non unicode character by empty string return } set sel [$listbox curselection] if {[llength $sel] > 1} { # Listbox has more than one selected item return } # Initialize index where search begin if {[llength $sel] == 1} { set startIndex [lindex $sel 0] } else { set startIndex 0 } if {[info exists data(searchPrefix)]} { set searchPrefix $data(searchPrefix) } else { set searchPrefix "" } if {[string equal -nocase $searchPrefix $key]} { # User presses twice the same key for the first char. # Search the next item which begin with that char (handled below). } else { append searchPrefix $key } # Skip current selected item if searchPrefix is one char # and selected item starts with this char. if {[llength $sel] == 1 && [string length $searchPrefix] == 1 && [string match -nocase "$searchPrefix*" \ [$listbox get $startIndex]]} { incr startIndex } # Now search for searchPrefix after current item, # and wrap if not found. foreach {start end} [list $startIndex end 0 $startIndex] { set index $start foreach item [$listbox get $start $end] { if {[string match -nocase "$searchPrefix*" $item]} { set newSelectedIndex $index break } incr index } if {[info exists newSelectedIndex]} { # We have found a new item, select it and stop search $listbox selection clear 0 end $listbox selection set $newSelectedIndex $listbox see $newSelectedIndex break } } # Bufferize searchPrefix. Discard it in a small delay if {[info exists data(afterId)]} { after cancel $data(afterId) } set data(searchPrefix) $searchPrefix set data(afterId) [after 1000 "unset ::ListboxQuickSelect:$listbox"] } # --- Test code --- package require Tk set listbox [listbox .listbox] eval $listbox insert end [lsort [glob -nocomplain -directory / -tail *]] bind $listbox <KeyPress> { ListboxQuickSelect %W %A } focus $listbox pack $listbox
ulis, 2003-05-21: Hugecombo has this functionality implemented. And has also a search-by-pattern implemented.
Hugecombo: http://perso.wanadoo.fr/maurice.ulis/tcl/Hugecombo 404 Broken Link
TS - Searching list box entries via entry box (ActiveState Cookbook) . This code allows users to search the entries in a list box while typing them in an entry box. Easily changeable to search through different indexes of the list entries.
MHo - See Listbox navigation by keyboard