Version 17 of ttk::combobox

Updated 2010-02-25 02:25:34 by jnc

Ttk's combobox widget.

http://www.tcl.tk/man/tcl8.5/TkCmd/ttk_combobox.htm

TR - I saw that the combobox of the Tile package didn't support autocompletion, so I added it using the code from BWidget:

 proc ComboBoxAutoComplete {path key} {
        #
        # autocomplete a string in the ttk::combobox from the list of values
        #
        # Any key string with more than one character and is not entirely
        # lower-case is considered a function key and is thus ignored.
        #
        # path -> path to the combobox
        #
        if {[string length $key] > 1 && [string tolower $key] != $key} {return}

        set text [string map [list {[} {\[} {]} {\]}] [$path get]]
        if {[string equal $text ""]} {return}

        set values [$path cget -values]
        set x [lsearch $values $text*]
        if {$x < 0} {return}

        set index [$path index insert]
        $path set [lindex $values $x]
        $path icursor $index
        $path selection range insert end
 }

All you need to do now, is binding <KeyRelease> to this procedure:

 package require Tk 8.5
 package require tile
 ttk::combobox .c -values [list one two three four five six seven]
 pack .c -padx 5 -pady 5
 bind .c <KeyRelease> [list ComboBoxAutoComplete .c %K]

CLN 2006-04-20 - Shouldn't this be in a namespace or at least be named ttkComboBoxAutoComplete? For that matter, why not submit a patch to get this into the Tile distribution. (Not that I wouldn't be grateful to have it available here in the mean time if I was using Tile.)

TR 2006-04-21 - I just read the tile paper [L1 ] by Rolf Ade. It mentions autocompletion code in the demos directory of the tile distribution. I haven't used that code yet, but it seems to do the same job as the code above, just in the correct namespace and as a command like

 tile::combobox::enableAutocomplete

So, the above code is not needed, really ...


jnc Feb 5, 2010 - Here is complete auto-complete code. This code completes while in an editable or readonly combobox. It also completes the with a key press when in the drop down list from the combobox. At the bottom is a simple example.

 package require Tk

 namespace eval ttk::combobox {}

 # Required to escape a few characters to to the string match used
 proc ttk::combobox::EscapeKey {key} {
     switch -- $key {
         bracketleft  { return {\[} }
         bracketright { return {\]} }
         asterisk     { return {\*} }
         question     { return {\?} }
         default      { return $key }
     }
 }

 proc ttk::combobox::CompleteEntry {W key} {
     if {[string length $key] > 1 && [string tolower $key] != $key} {return}

     if {[$W instate readonly]} {
         set value [EscapeKey $key]
     } else {
         set value [string map { {[} {\[} {]} {\]} {?} {\?} {*} {\*} } [$W get]]
         if {[string equal $value ""]} {return}
     }

     set values [$W cget -values]
     set x [lsearch -nocase $values $value*]
     if {$x < 0} {return}

     set index [$W index insert]
     $W set [lindex $values $x]
     $W icursor $index
     $W selection range insert end

     if {[$W instate readonly]} {
         event generate $W <<ComboboxSelected>> -when mark
     }
 }

 proc ttk::combobox::CompleteList {W key} {
     set key [EscapeKey $key]

     for {set idx 0} {$idx < [$W size]} {incr idx} {
         if {[string match -nocase $key* [$W get $idx]]} {
             $W selection clear 0 end
             $W selection set $idx
             $W see $idx
             $W activate $idx
             break
         }
     }
 }

 bind ComboboxListbox <KeyPress>   { ttk::combobox::CompleteList %W %K }
 bind TCombobox       <KeyRelease> { ttk::combobox::CompleteEntry %W %K }

 set values {One Two Three Four Five *Hello ?Hello [Hello] Six Seven Eight Nine Ten}

 ttk::label .l1 -text Readonly
 ttk::combobox .c1 -state readonly -values $values
 ttk::label .l2 -text Editable
 ttk::combobox .c2 -values $values

 bind .c1 <<ComboboxSelected>> { puts [.c1 get] }
 bind .c2 <<ComboboxSelected>> { puts [.c2 get] }

 pack .l1 .c1 .l2 .c2

RLH It would be nice if a widget is involved to see a graphic showing the widget. Not necessary...but nice.


D. McC 2008 Dec 8: OK, after rummaging through the ttk::style man page and trying things out in vain, I give up. Can somebody tell me how to specify the background color for the entry portion of the ttk::combobox? And can somebody tell me why there is not even an option to specify colors of Ttk widgets in the same ultra-simple way as for Tk widgets, e.g., "-bg AntiqueWhite"?

Bryan Oakley 2008 Dec 8: To solve your immediate problem, try this:

 ttk::combobox .cb -style mycombobox.TCombobox
 ttk::style configure mycombobox.TCombobox -fieldbackground bisque

(using "ttk::style map" may be a better choice, but I'll leave that as an exercise for the reader)

As to why there is no option, that's the design philosophy of the themed widgets -- you lose some amount of control over individual widgets but gain the ability to create unified themes.


D. McC 2008 Dec 9: Thanks--it works! Now I'll see about incorporating that into my color-scheme files.

What I still don't understand is why the programmer isn't given a choice about how much control over individual widgets (and ease of configuring them) to trade off for how much ability to create unified themes.


TLT 2009-11-28 - I was annoyed that the ttk::combobox does not change the cursor to an ibeam when it is inside the text entry widget. The following binding fixes that:

 bind TCombobox <Motion> {
     if {[%W cget -state] eq "normal" && [%W identify %x %y] eq "textarea"} {
         %W configure -cursor xterm
     } else {
         %W configure -cursor ""
     }
 }
 pack [ttk::combobox .cb]

MHo: In the read-only-editfield, how is it possible, e.g. to get the entry Seven? Pressing S always leads to Six (prior in the list), pressing S again does not help, pressing E right after S leads to Eight. This is true for the listbox, too.

jnc: Feb 24, 2010: In my misc-tcl code project, there is updated combo box code. I have not updated it here yet as I don't want to make daily updates here. The code on the misc-tcl project page allows properly for the Up/Down use of arrow keys to select items when in the readonly edit field. So, to get to Seven, you would press S and then use your up/down arrow key to navigate to Seven. This is how Windows works. I would actually prefer it to allow allow typing of SE which would go to Seven, but this would be non-standard. I am sure you can modify the above code for that type of action if you so desired.

My miscellaneous Tcl code is located at: http://jeremy.cowgar.com/misctcl/index.cgi/index and the combobox code is specifically located at: http://jeremy.cowgar.com/misctcl/index.cgi/doc/tip/combobox/combobox.tcl .. That will always be my latest source. The source (as of Feb 24, 2010) has been submitted to Tcl/Tk as the default behavior. No action has been taken on it as of this time.