**Combobox Enhancements** [bll] 2015-9-1 Problem 1. The standard combobox has a fixed width. This is not particularly useful for localized text. Some localized text may be much longer than the default and other text may be much shorter. This set of routines adjusts the width of the combobox to match the width of the longest value in the combobox. It also resolves the problem of text updates and forgetting to adjust the corresponding combobox width. ====== variable vars # create a standard combobox and adjust the width of the combobox to # the longest value. # arguments are exactly the same as ttk::combobox proc comboBox { nm args } { ttk::combobox $nm {*}$args set wid [getComboBoxWidth $nm] $nm configure -width $wid return $nm } # update the combobox values. # The width will need to be recalculated. proc updComboBoxValues { nm values } { $nm configure -values $values set wid [getComboBoxWidth $nm] $nm configure -width $wid } # calculates the width needed to hold the longest value. # uses a cache to save processing time. proc getComboBoxWidth { nm } { variable vars set values [$nm cget -values] set svalues [join $values {}] if { [info exists vars(cb.list.cache.$svalues)] } { set wid $vars(cb.list.cache.$svalues) } else { set pwid 0 set font [$nm cget -font] foreach {val} $values { set pwid [expr {max($pwid,[font measure $font $val])}] } set wid [expr {$pwid / [font measure $font 0] + 1}] set vars(cb.list.cache.$svalues) $wid } return $wid } ====== Problem 2. Comboboxes cannot return values associated with the labels. For example, you might want to return 1-12 for the labels January-December. For localized text, it is much easier to return a standard value than to have to handle many different languages. For example, a simple yes/no drop down would be ja/nein in german, oui/non in french, etc. Having code that checks for every possible return value for every localized combobox would be insane. Reverse translating each combobox isn't as bad, but gets messy as the number of comboboxes grows. An example from HTML: You can have: The display name 'Volvo' returns the value 'volvo'. [I really don't understand how this has never yet gotten into tk] [http://core.tcl.tk/tk/tktview?name=15d172dd7a %|%RFE for this functionality] ====== # this procedure could use a much better api # vv : the variable name used to save the return value # normally this would have been passed to -textvariable. # vallist : a list of values to return. # The selected combobox value is mapped to the corresponding value in this list. # The length of this list must match the length of the -values list. # dflt : the default value to set the combobox to. # normally, this would be whatever value -textvariable has. # But the value of [set $vv] is from $vallist, not -values. # nm : The name of the combobox # args : standard combobox arguments. # proc assocComboBox { vv vallist dflt nm args } { comboBox $nm {*}$args ; # uses the auto-width routine above..replace with ttk::combobox for the standard. $nm set $dflt bind $nm <> +[list uiutils::setAssocComboBoxVal $vv $vallist $nm] bind $nm +[list uiutils::setAssocComboBoxVal $vv $vallist $nm] return $nm } # sets the return value (from $vallist) for the associated combobox to the selection corresponding # to the combobox value (-values). proc setAssocComboBoxVal { vv vallist nm } { upvar $vv v set curr [$nm current] set v [lindex $vallist $curr] } # helper routine to update the combobox's current value proc updAssocComboBoxVal { nm v } { $nm set $v } ====== <> Widget | Tk