#!/usr/bin/perl use strict; use warnings; use Tk; my $mw = MainWindow->new(-title => 'Mac Address Input Example'); my $fr = $mw->Frame()->pack(-expand => 1, -fill => 'both'); my $lb = $fr->Label(-text => 'MAC Address')->pack(-side => 'left'); # widget used to display Entry field errors my $errW = $fr->Label(-foreground=>'red')->pack(-side=>'bottom'); # hash to hold Entry widgets my %entries; # loop thru the number of Entry widgets desired for(1..6){ # create the Entry widget $entries{$_}{'entry'} = $fr->Entry( -textvariable => \$entries{$_}{'addy'}, -width => 3, ); # save default widget background $entries{$_}{'bg'} = $entries{$_}{'entry'}->cget('-bg'); # pack/display the widget $entries{$_}{'entry'}->pack(-side => 'left'); } # loop back thru the created widgets for(1..6){ # put some bogus values in for testing... $entries{$_}{'addy'} = ($_>1) ? $_.$_ : ''; $entries{$_}{'addy'} .= 'z' if($_ == 3 or $_ == 4); # configure the validation for the widget $entries{$_}{'entry'}->configure( # -validate => 'focusout', -validate => 'all', -validatecommand => [ \&validate,$_ ], -invalidcommand => [ \&show_invalid,$entries{$_}{'entry'},$_ ], ); } # put focus on initial Entry widget $entries{1}{'entry'}->focus(); # auto-tab thru all Entry widgets to perform validation on pre-populated values for(1..6){ $mw->eventGenerate(''); # $mw->idletasks; $mw->after(100); $mw->update; } MainLoop(); sub clear_err { my($num) = @_; $errW->configure(-text=>''); $entries{$num}{'entry'}->configure(-bg=>$entries{$num}{'bg'}); } # returns `1' if valid, and `0' if invalid sub validate { my($num,$val) = @_; unless($val){ print "Field $num has nothing to validate\n";return 1;} my $valid = ($val =~ /^[0-9a-f]{1,2}$/i) ? 1 : 0; printf "Field %s, validating \`%s'...%s\n",$num,$val,$valid? "ok": "FAILED"; if($valid){ # clear error widget &clear_err($num); # re-enable all other widgets for(1..6){ next if(/^$num$/); $entries{$_}{'entry'}->configure(-state=>'normal'); } }else{ # update the error widget with text indicating a problem with the value $errW->configure(-text=>"Field $num value \`$val' is invalid"); } return $valid; } sub show_invalid { my($widget,$num) = @_; $widget->focus(); # turn the background of the problem field to red my $bg = $widget->cget('-bg'); $widget->configure(-bg => 'red'); $widget->update(); # temporarily disable focus on all other widgets for(1..6){ next if(/^$num$/); $entries{$_}{'entry'}->configure(-state=>'disabled'); } }