|
From: Jeff H. <je...@Ac...> - 2005-09-20 01:49:26
|
Take a simple validated entry widget:
package require tile
proc isValid {e str} {
set ok [file isfile $str]
$e configure -bg [expr {$ok ? "white" : "lightyellow"}]
return 1
}
proc getfile {e var} {
set tmp [tk_getOpenFile -title "Select File"]
if {$tmp ne ""} {
set $var $tmp
}
}
destroy .classic
set t [toplevel .classic]
set e [entry $t.e -textvariable ::myvar -validate key \
-validatecommand [list isValid %W %P]]
button $t.b -text "..." -command [list getfile $e ::myvar]
pack $t.e $t.b -fill x -side left
pack configure $t.e -expand 1
# now in Tile, the "obvious" translation:
# only -foreground seems reliably controllable
style map TEntry -foreground {invalid \#FF0000}
proc isValidTtk {e str} {
set ok [file isfile $str]
$e state [expr {$ok ? "!invalid" : "invalid"}]
return 1
}
proc getfileTtk {e var} {
set tmp [tk_getOpenFile -title "Select File"]
if {$tmp ne ""} {
set $var $tmp
}
}
destroy .ttk
set t [toplevel .ttk]
set e [ttk::entry $t.e -textvariable ::myvarttk -validate key \
-validatecommand [list isValidTtk %W %P]]
ttk::button $t.b -text "..." -command [list getfileTtk $e ::myvarttk]
pack $t.e $t.b -fill x -side left
pack configure $t.e -expand 1
Now just type in (don't use the ... yet). You will see that
the above doesn't work at all. The problem is that the entry
widget sets the "invalid" bit to whatever is return by the
-validatecommand. OK, let's try this instead:
proc isValidTtk {e str} {
set ok [file isfile $str]
return $ok
}
OK, this will work if the entry starts in an invalid state, as
tile does some internal state handling that way. However, we
get to any valid state, and we are "locked" there, not able to
type anything else, which is what we were avoiding in the first
place.
OK, so let's consider the ... cases. I'm setting the textvar
directly. The behavior difference here is a known variance,
but it only make editing more difficult. If we get into an
invalid state, we would have to recall '$e validate' on any
getfileTtk call to force validate. Try to control all via the
entry widget instead:
proc getfileTtk {e var} {
set tmp [tk_getOpenFile -title "Select File"]
if {$tmp ne ""} {
$e delete 0 end
$e insert 0 $tmp
}
}
So this will handle validation ... but wait, it doesn't work
at all if you have the strict validation on. You have to set
-validate none, edit entry, then reset validation.
All in all, it seems like we've lost the flexibility that we
used to have ...
I guess I need a paradigm shift, going back to a whole bunch
of triggers on variable tracing instead, but this is a step
backwards IMO. Or am I missing something?
Jeff
|