Version 2 of Labelled Scale Widget with Toggled Keyboard Entry

Updated 2005-03-16 10:36:27

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. This code snippet might be of use. 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 original slider position.

In the code below there is no entry validation so expect some errors. Other alternatives might be deleting the Ent <Return> to offer the bare choice between intput methods.

 ----

 package require Tk
 proc newscale {w title variable from to} {
    #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
    #itneractive 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 -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 value 50
    newscale .sc {Range: } value 0 100
    pack .sc -side left
 }
 demo