This is something that has stumped me for some time. As a recent re-convert back to Tcl I needed to solve a problem regarding a dynamic Tk interface that I needed more control over the Tab and Shift-Tab Sequence for how a user would navigate through the interface using the Keyboard. After a lot of digging, and talking to the guys at ActiveState, I came up with the following. Assume you have 5 entry fields that you needed to control the tab sequence through. ====== set count 1 foreach item [list .one .two .three .four .five] { frame .fr$count pack .fr$count label .l_$count -text "ITEM: $count" entry $item pack .l_$count $item -side left -in .fr$count incr count } ====== By default, Tk's focus model will be going to the next widget that is displayed - which is OK if you are always building your interfaces based on the default tab-sequence that Tk expects. But most of my code does not work around the tab-sequece. (I just don't think or plan my code around that level of detail in life). To solve this, you can override the default bindings and replace them with your own hard coded ones, or a new binding that allows more control over what is next. The default binding is as follows: ====== # default bindings for --- execute "bind all " tk::TabToWindow [tk_focusNext %W] ====== Here is the override I created: ====== # Override the Bindings bind all {break} bind all {break} ====== This effectively overrides ALL Tab and Shift-Tab bindings to a NULL return/action. Now to fix the binding to do your own thing: ====== # Add Custom Binding bind {customTabSeq %W next} bind {customTabSeq %W prev} ====== The above will call a process called customTabSeq that will pass in the current widget and the direction of tab you want to do. Here is the code for the customTabSeq: ====== # Custom Tab Sequence Procedure proc customTabSeq {w direction} { set currentWidget $w set base ".[lindex [split $w .] 1]" set widgetPath ".[string trimleft $w .$base]" # list of input elements that I want to sequence through set tabSequence [list <>] set curLocation [lsearch $tabSequence $currentWidget] puts "Current Location: $curLocation" if {[string match $direction next]} { if {[string match $currentWidget [lindex $tabSequence end]]} { set newLocation [lindex $tabSequence 0] } else { set newLocation [lindex $tabSequence [expr $curLocation + 1]] } } else { if {[string match $currentWidget [lindex $tabSequence 0]]} { set newLocation [lindex $tabSequence end] } else { set newLocation [lindex $tabSequence [expr $curLocation - 1]] } } focus -force $newLocation } ====== FULL WORKING EXAMPLE ====== bind all {break} bind all {break} set count 1 foreach item [list .one .two .three .four .five] { frame .fr$count pack .fr$count label .l_$count -text "ITEM: $count" entry $item bind $item {customTabSeq %W next} bind $item {customTabSeq %W prev} pack .l_$count $item -side left -in .fr$count incr count } proc customTabSeq {w direction} { set currentWidget $w set base ".[lindex [split $w .] 1]" set widgetPath ".[string trimleft $w .$base]" # list of input elements that I want to sequence through set tabSequence [list .five .three .one .four .two] set curLocation [lsearch $tabSequence $currentWidget] if {[string match $direction next]} { if {[string match $currentWidget [lindex $tabSequence end]]} { set newLocation [lindex $tabSequence 0] } else { set newLocation [lindex $tabSequence [expr $curLocation + 1]] } } else { if {[string match $currentWidget [lindex $tabSequence 0]]} { set newLocation [lindex $tabSequence end] } else { set newLocation [lindex $tabSequence [expr $curLocation - 1]] } } puts "MOVING FROM $currentWidget ---> $newLocation" focus -force $newLocation } ====== Hope this helps others out there also....