Fellow monks,

I've been scratching my head for several hours over this, and even after simplifying it to about 130 lines, I still can't make heads or tails of what's going on.

The program simply draws a chosen shape in the Canvas.  The shape is chosen from an Optionmenu, which modifies the global variable $shape.  This modification, in turn, causes a validation subroutine new_shape() to be called, as a result of a -validatecommand option.

The -validatecommand option seems to work fine, up to a point.  As soon as the first option "Choose shape" is selected, the shape no longer appears, leading me to believe that the validation is no longer being performed.

Strangely, the behavior gets worse when the $mw->update line is uncommented out (in the section marked "Anomaly #1").  In that case, only the first shape chosen takes effect; any others do not display.  I'm supposing that this behavior is due to trying to perform an update during a validation, which I could understand might be problematic.

Even stranger, though, is what happens when the debug line printf "TFD> ppoints => %s\n", Dumper($ppoints); is uncommented out (in the section marked "Anomaly #2").  In that case, the program works as expected, and new shapes can again be chosen after selecting the "Choose shape" option!

Can anyone shed light on what's going on here?  Can someone suggest a way to fix this, or a better way to do it?  Thanks in advance for any insights!

#!/usr/bin/perl # Strict; use strict; use warnings; # User-defined my $pshapes = [ [ 'Choose shape' => "" ], [ 'triangle' => "80,100,60:360,-120x2" ], [ 'square' => "100,100,90:320,-90x3" ], [ 'pentagon' => "100,290,36:200,-72x4" ], [ 'hexagon' => "80,250,60:180,-60x5" ], ]; # Libraries use File::Basename; use Data::Dumper; use Tk; # Globals my $shape = ""; # Algorithm for drawing shape my $ppoints = [ ]; # Point data ( [x0, y0, x1, y1, id] ) my $mw = ""; # Main Window object my $cv = ""; # Canvas object my $cvfr = ""; # Canvas frame #################### ### Main program ### #################### create_gui(); ################### ### Subroutines ### ################### sub create_gui { my $ver = $Tk::VERSION; $mw = new MainWindow(-title => "Shape chooser (Tk version $ver)"); my $f1 = $mw->Frame()->pack(-expand => '0', -fill => 'x'); $cvfr = $mw->Frame()->pack(-expand => '1', -fill => 'both'); my $b1 = $f1->Button(-text => 'Exit (Esc)', -bg => 'skyblue'); $b1->configure(-command => sub { $mw->destroy() }); $b1->pack(-side => 'right'); $mw->bind("<Escape>" => sub { $b1->invoke() }); my $om = $f1->Optionmenu(-options => $pshapes, -variable => \$shap +e); $om->pack(-side => 'left'); my $fr = $f1->Frame()->pack(-side => 'left'); $fr->Label(-text => ' Shape: ')->pack(-side => 'left'); my @vopts = (-validate => 'focusout', -validatecommand => \&new_sh +ape); my $en = $fr->Entry(-width => 50, -textvar => \$shape, @vopts); $en->pack(-side => 'left'); $cv = $cvfr->Canvas(-bg => 'black', -height => 512, -width => 512) +; $cv->pack(); MainLoop; } sub new_shape { print "\nChanging shape...\n"; # Clear canvas foreach my $ppoint (@$ppoints) { my $id = $ppoint->[-1]; $cv->delete($id); } $ppoints = draw_shape($shape); # Anomoly #1 # # Uncommenting the following line allows only ONE shape to be draw +n!?? # # $mw->update; # Anomoly #2 # # Uncommenting the following line makes everything suddenly work!? +? # # printf "TFD> ppoints => %s\n", Dumper($ppoints); } sub draw_shape { my ($shapestr) = @_; my $pnewpoints = [ ]; my @shapeargs = split(',', $shapestr); printf "Shape args [%s]\n", Dumper([@shapeargs]); my $pargs = [ -fill => 'pink', -width => 2 ]; if (@shapeargs > 1) { my $x = my $x0 = shift @shapeargs; my $y = my $y0 = 512 - shift @shapeargs; my ($r, $q); for (@shapeargs) { if ($_ eq '+') { my @pts = ($x, $y, $x0, $y0); my $ppoint = [ @pts, $cv->createLine(@pts, @$pargs) ]; push @$pnewpoints, $ppoint; last; } my ($ang, $sep, $N) = /(-?\d+)([:x]?)(-?\d+)?/; ($sep eq ':') and ($N,$r) = (1,$N); $N ||= 1; while ($N--) { $q += $ang; my $newq = (180 + $q) / 57.2957; my ($dx, $dy) = ($r * cos($newq), $r * sin($newq)); my ($x1, $y1) = ($x - $dx, $y + $dy); my @pts = ($x, $y, $x1, $y1); my $ppoint = [ @pts, $cv->createLine(@pts, @$pargs) ]; push @$pnewpoints, $ppoint; ($x, $y) = ($x1, $y1); } } } $mw->update(); return $pnewpoints; }

s''(q.S:$/9=(T1';s;(..)(..);$..=substr+crypt($1,$2),2,3;eg;print$..$/

In reply to Strange behavior in -validatecommand; Win32 Perl/Tk version 804.027 by liverpole

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.