tags:

views:

66

answers:

2

The BWidget ComboBox widget allows you to fill in an entry field with a value. I would like to enforce only specific characters in that field (e.g. only [a-z0-9]). For that purpose I would like to use Tcl/Tk's -validatecommand (or -vcmd for short), just as you do with the standard 'entry' widget:

proc ValidateMyEntry { value } {
    # Check if it's alphanum string

    if ![regexp {^[-a-zA-Z0-9]*$} $value] {
        return 0
    }
    return 1
}

entry .my_entry -width 20 -textvariable myVar -validate key -vcmd {ValidateMyEntry %P}

It seems ComboBox does not support -validatecommand. What's the best work-around?

A: 

If you want to use a BWidget, you can try with -modifycmd or -postcommand.

Anyway I would suggest you to try the ttk::combobox with the -postcommand option.

Carlos Tasada
Yes, I can use -modifycmd, but it only triggers after an (illegal) value has been filled in. So if I want to prevent a space, with -vcmd the space will not even be inserted, while with modifycmd it is inserted and you should remove it later on.
Roalt
I have a restriction on using Tcl/Tk 8.4 for now. ttk::combobox is included in Tcl/Tk 8.5.
Roalt
The other option (which I haven't tested) is to use the -textvariable option, and add a trace to the variable.In any case you'll need to remove the unsupported characters.The last option, and this one requires extra work, is to capture the "focus in" of your combobox and show an entry in the same coordinates. It's tricky but I did something similar some years ago.
Carlos Tasada
Yes. I've considered that as well as I used it in a Pre Tcl 8.4 era when there was not yet a -validatecommand.
Roalt
A: 

As something that was possible but a bit cumbersome, I decided to use the old-style 'trace variable' function to enforce values in combobox.

Put the following statement after the ComboBox call:

trace variable myVar w forceAlphaNum

Elsewhere, you have to define the forceAlphaNum proc:

proc forceAlphaNum { name el op } {
    if { $el == "" } {
        set newname $name
        set oldname ${name}_alphanum
    } else {
        set newname ${name}($el)
        set oldname ${name}_alphanum($el)
    }

    global $newname
    global $oldname

    if { ![info exist $oldname] } {
        set $oldname ""
    }    

    # Check if it's alphanum string
    if ![regexp {^[a-zA-Z0-9]*$} [set $newname]] {
        set $newname [set $oldname]
        bell; return
    }
    set $oldname [set $newname]
}
Roalt