WJG March 16th 2005 - If scale widgets are crammed together or have a restricted area on screen then offering the user the option to enter numbers directly through the keyboard can be an advantage. This may be especially true if the user has some specific number in mind and dragging sliders can be, well, a drag. For those crafting a GUI with lots of sliders crammed into a tight space then this code snippet might be of use.
The code is pretty-simple and needs no clarification. Regarding the bindings, perform a simple Double-Button-1 click on the slider title and a entry field will appear displaying the current slider value. Pressing Return in the entry field or a further Double-Button-1 click on the title to restore the original scale widget.
User modifications might include deleting the Entry widget <Return> binding to offer the bare choice between input methods and provide additional variable handling code to allow doubles to be managed through the slider (it defaults to integers}.
package require Tk proc newscale {w title variable from to} { #define this proc first to prevent interpreter error proc _[set w].ent {val} { return [expr {[string is integer $val] || [string match {[-+]} $val]} ] } #create widget holder frame $w -borderwidth 2 -relief ridge -height 10 label $w.lab -text $title -anchor w pack $w.lab -side left #alternative kb entry method entry $w.ent -textvariable $variable -validate all -vcmd "_$w.ent %P" #interactive slider with value frame $w.fr2 label $w.fr2.lab -textvariable $variable -anchor w -width 3 pack $w.fr2.lab -side left scale $w.fr2.sc -orient horizontal -borderwidth 1 \ -showvalue 0 -variable $variable \ -width 8 -sliderlength 10 \ -from $from -to $to pack $w.fr2.sc -side left pack $w.fr2 -side left #bindings bind $w.lab <Double-Button-1> { if {[winfo ismapped [winfo parent %W].fr2.sc] } { [winfo parent %W].ent delete 0 end [winfo parent %W].ent insert 0 [[winfo parent %W].fr2.lab cget -text ] pack [winfo parent %W].ent focus [winfo parent %W].ent pack forget [winfo parent %W].fr2 } else { #set global variable value pack [winfo parent %W].fr2 pack forget [winfo parent %W].ent -fill x } } bind $w.ent <Return> { pack forget %W pack [winfo parent %W].fr2 } } proc demo {} { set w .fr1 set ::v(1) -33 set ::v(2) 0 set ::v(3) 33 newscale .sc1 {Range1: } ::v(1) -100 100 newscale .sc2 {Range2: } ::v(2) -100 100 newscale .sc3 {Range3: } ::v(3) -100 100 pack .sc1 .sc2 .sc3 -side top } demo