Hi gurus, monks, monkeys, and other caffeinated types,

I have a small Tk gui that uses Tk::Entry input to get a MAC. I got most of the code from an old thread here. It works great, but I found a weird bug:

When I put invalid text into a field that represents a MAC octet (e.g. "zz"), and then try to leave the field (via Tab key or mouse-click), it properly forces me back into the field with the errant entry.

The problem is, if I hit the Tab key twice in quick succession, it will pop me out of the bad field, and what's more (worse), will seem to "forget" about the field, as you will see if you run the code.

To replicate, enter "zz" in a field, double-hit Tab quickly, then hit Tab regularly to hop thru the other (blank) fields. When you come back around to the "zz" field, it won't run the validation check again - no matter if the bad string is removed/replaced, etc.

#!/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'); my %entries; for(1..6){ $entries{$_}{'entry'} = $fr->Entry(); $entries{$_}{'entry'}->configure( -textvariable => \$entries{$_}{'addy'}, -width => 3, -validate => 'focusout', -validatecommand => [ \&validate,$_ ], -invalidcommand => [ \&show_invalid,$entries{$_}{'entry'} ], ); $entries{$_}{'entry'}->pack(-side => 'left'); } MainLoop(); # 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"; return $valid; } sub show_invalid { my($widget) = @_; $widget->focus(); # temporarily flash the background of the problem field in red my $bg = $widget->cget('-bg'); $widget->configure(-bg => 'red'); $widget->update(); # effect a sleep of 200 milliseconds select(undef,undef,undef,0.2); # return the background color to the original state $widget->configure(-bg => $bg); $widget->update(); }

Edit: If you can't replicate the problem using the Tab key, it also seems to happen if you pre-populate a field's textvariable with an invalid string.

For example, inserting this line into the loop will make the 3rd field fail initial validation, but will allow focus to pass thru it without subsequently attempting validation:

for(1..6){ $entries{$_}{'addy'} = 'zz'.$_ if($_ == 3);

In reply to Tk::Entry and double-Tab key weirdness by atreyu

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.