G'day Zsolt,

You have written your for loop like this:

for (INIT; COND; INCR) { ... }

The following is very important. I'm not attempting to be patronising; you need to fully understand this. Pay close attention to the numbers.

INIT
This is an initialisation which only occurs once. In your case, it sets $i to 1.
COND
This is a condition which determines whether the loop is entered. When $i is 1, 2, 3, 4 or 5 the condition $i <= 5 is TRUE and the loop is entered. When $i is 6, the condition is FALSE, and the loop ends.
INCR
This increments $i at the end of the loop before another iteration is attempted. $i is set to 2 at the end of the 1st iteration. It continues to be incremented. $i is set to 6 at the end of the 5th iteration. The last value that $i has is 6!

In each iteration, you set up two callbacks with the -command option. In both cases, the value of the callback is a coderef (an anonymous subroutine: sub { ... }); You redefine those coderefs on each iteration. The code in those coderefs contains the variable $i. On the final redefinition, the last value that $i has is 6!

This is why, regardless of which CLR button you use, you always see "title: Choose color for 6 degree!"; and similarly, regardless of which CHK button you use, you always see "degreeClr6".

Using (non-reference) variables in a callback is almost always a bad idea in Tk applications: use references instead. Here's a somewhat contrived Tk application using two scalarrefs and an arrayref in a callback. It's possibly a little over the top; however, it's intended to make a point.

#!/usr/bin/env perl use strict; use warnings; use Tk; my $mw = MainWindow::->new(); my @colours = qw{magenta red blue green darkred}; my $swatch = $mw->Label(-bg => 'black')->pack(-fill => 'x'); for my $i (0 .. 4) { $mw->Button( -bg => $colours[$i], -command => sub { colour_swatch(\$swatch, \@colours, \$i); }, )->pack(-fill => 'x'); } sub colour_swatch { my ($swatch_ref, $colours_ref, $i_ref) = @_; my $bg = ${$colours_ref}[$$i_ref]; $$swatch_ref->configure(-bg => $bg); return; } MainLoop;

The swatch at the top starts off black. As you click on any of the five coloured buttons below, it takes on the colour of that button.

You have no end of other problems with the code you posted: package variables springing into existence all over the place; symbolic references which you should really avoid (arrays and hashes are often a better choice — see @colours in my code above); lines so long that they're almost unreadable (one statement has 262 characters); and other code which I suspect you just threw at it in the hope that it would somehow fix something (for instance, what did think the utf pragma would achieve?).

I strongly recommend that you read perlintro to get a basic grounding in Perl coding. Following that, you may want to look at: "Symbolic references", "Anonymous Subroutines", and Tk::callbacks.

— Ken


In reply to Re: Strange behavior of iteration while creating Perl/Tk widgets dynamically by kcott
in thread Strange behavior of iteration while creating Perl/Tk widgets dynamically by Vasek

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.