The following (not extensively tested) procedures seem to handle the enabling and disabling of widget sets. Just pass in the name of the frame as the argument to each procedure, and all children of that frame are disabled or enabled. I suspect the problem you had was when you tried to set the
-state option for widgets that didn't support it (like a listbox). My quick-and-dirty solution is to use
catch to ignore any errors that occur when setting that option.
Code:
proc disable {parent} {
set widgets [info commands $parent*]
foreach w $widgets {
catch {$w configure -state disabled}
}
}
proc enable {parent} {
set widgets [info commands $parent*]
foreach w $widgets {
catch {$w configure -state normal}
}
}
As for your second question, as you discovered, setting the
-width option of an entry widget controls only the number of characters displayed (the visible width), not the number of characters that can be entered. You've got a couple of choices to limit the number of characters entered.
First, and probably best, is to use the validation feature of the entry widget. But this requires Tcl version 8.3 or later. To enable validation, you must use the
-validate option to specify when validation should occur, and the
-validatecommand option to perform the actual validation. Read the entry widget documentation for more information on using these options, but here's a simple example of what you requested:
Code:
proc limit {newstr length} {
return [expr {[string length $newstr] <= $length}]
}
entry .e -width 10 -validate all -validatecommand {limit %P 6}
pack .e
The second option, which you'll have to use if you're using a version of Tcl earlier than 8.3, is to check all insertions into the entry widget to prevent more than the maximum number of characters being inserted. There are several strategies for doing so, but the one I like best is to "intercept" the entry's
insert operation. This works well because all operations that insert text into an entry widget -- including operations like pasting from the clipboard -- eventually call the widget's
insert operation. You can learn more about this technique at the Tcl'ers Wiki (
on the page "Overloading widgets,"
Code:
proc max6entry {w args} {
# create the "base" entry
eval entry $w $args
# keep the original widget command
rename $w _$w
# Install the alias...
interp alias {} $w {} max6_instanceCmd $w
return $w
}
proc max6_instanceCmd {self cmd args} {
switch -- $cmd {
insert {
# Sanity check the proposed insertion
set index [lindex $args 0]
set newtext [lindex $args 1]
set curlength [_$self index end]
# Truncate the new text if necessary
set newtext [string range $newtext 0 [expr {5-$curlength}]]
_$self insert $index $newtext
}
default {
return [uplevel 1 [list _$self $cmd] $args]
}
}
}
- Ken Jones, President
Avia Training and Consulting
866-TCL-HELP (866-825-4357) US Toll free
415-643-8692 Voice
415-643-8697 Fax