From: Daniel Burgaud [mailto:burg...@gmail.com] 
Sent: 03 September 2009 03:00
To: Brian Raven
Cc: Perl-Win32-Users
Subject: Re: need help with Tk: I could not figure the error

> Hi
> 
> When I moved all the variables within the subroutines outside, this
script suddenly worked flawlessly.
> 
> What gives?
> 
> Wasnt it highly desireable to "localize" variables to make it more
organized?
> yet when i did just that, it fails to run. Only when I made all
variables GLOBAL
> that it worked.

I have rewritten your code a bit to be more like how I would approach
it. Note no nested subs, no interfering with the main event loop,
passing variables need by callbacks as parameters rather than hoping
that they are in scope, and avoiding some code duplication. It seems to
do pretty much what I understand you were trying to do.

----------------------------------------------------
use strict;
use warnings;
use Tk;

my $BGColor0 = "#D8D0C8"; 
my $BGColor1 = "#D0D0D0"; 
my $BGColor2 = "#808080";
my $BGColor3 = "#5090C0";
my $BGColor4 = "#4070A0";
my $BGColor5 = "#80C080";
my $BGColor6 = "#408040";
my $BGColor7 = "#FFFFFF";
my $BGColor8 = "#E0E0E0";
my $BGColor9 = "#FF8080";

my $mw = MainWindow->new;
$mw->title("MainWindow");
$mw->Button(-text => "Get Number",
            -command => sub {my $n = GetNumber('Enter Number');
                             print "Got '$n'\n";})->pack( );

MainLoop;

sub AddNumber {
    my ($numref, $key, $top) = @_;
    if ('0123456789' =~ $key) {
        $$numref .= $key;
    } elsif ($key eq 'period' && $$numref !~ /\./) {
        $$numref .= '.';
    } elsif ($key eq 'Return') {
        $top->destroy;
    } elsif ($key eq 'Escape') {
        $$numref = '';
        $top->destroy;
    } elsif ($key eq 'BackSpace') {
        chop($$numref);
        chop($$numref) if substr($$numref,-1) eq '.';
    }
}

sub Keyboard {
    my ($numref, $widget, $top) = @_;
    my $e = $widget->XEvent;    # get event object
    my $key = $e->K;
    AddNumber($numref, $key, $top);
}

sub MakeButton {
    my ($top, $widget, $label, $value, $numref, $fontsize) = @_;
    $fontsize ||= 30;
    my @buttonargs = (-borderwidth=>3,
                      -bg=>$BGColor3,
                      -activebackground=>$BGColor4,
                      -width=>4,
                      -height=>1,
                      -text => $label,
                      -font=>['Courier',$fontsize,'bold']);
    if (ref($value) eq 'CODE') {
        return $widget->Button( @buttonargs,
                                -command => $value );
    }
    return $widget->Button( @buttonargs,
                            -command => [\&AddNumber, $numref, $value,
$top]);
}

sub GetNumber {
    my $title = shift;
    my $number = 0;

    my $top = $mw->Toplevel(-title=>$title);
    $top->resizable(0,0);
    $top->transient($top->Parent->toplevel);

    $top->Label( -borderwidth=>2,
                 -bg=>$BGColor3,
                 -fg=>'#000000',
                 -font=>['Arial',20,'bold'],
                 -relief=>'groove',
                 -anchor=>"c",
                 -text=>$title)->pack( -side=>"top",
                                       -expand=>1,
                                       -fill=>'x' );

    $top->Label( -borderwidth=>4,
                 -bg=>$BGColor7,
                 -fg=>'#000000',
                 -font=>['Arial',40,'bold'],
                 -relief=>'groove',
                 -anchor=>"e",
                 -textvariable=>\$number)->pack( -side=>"top",
                                                 -expand=>1,
                                                 -fill=>'x' );

    my $frame = $top->Frame( -borderwidth=>2 )->pack( -side=>'left',
                                                      -expand=>1,
                                                      -fill=>'both');
    MakeButton($top, $frame, 7, 7, \$number)
        ->grid(MakeButton($top, $frame, 8, 8, \$number),
               MakeButton($top, $frame, 9, 9, \$number),
-sticky=>'news');
    MakeButton($top, $frame, 4, 4, \$number)
        ->grid(MakeButton($top, $frame, 5, 5, \$number),
               MakeButton($top, $frame, 6, 6, \$number),
-sticky=>'news');
    MakeButton($top, $frame, 1, 1, \$number)
        ->grid(MakeButton($top, $frame, 2, 2, \$number),
               MakeButton($top, $frame, 3, 3, \$number),
-sticky=>'news');
    MakeButton($top, $frame, 0, 0, \$number)
        ->grid(MakeButton($top, $frame, '.', 'period', \$number),
               MakeButton($top, $frame, 'Enter',
                          sub{$top->destroy}, undef, 20)
               , -sticky=>'news');

    $top->bind('<KeyPress>'=>sub{Keyboard(\$number, $_[0], $top)});
    $top->focus;
    $top->grab;
    $top->waitWindow;
    return $number;
}
----------------------------------------------------

HTH

-- 
Brian Raven 
This e-mail may contain confidential and/or privileged information. If you are 
not the intended recipient or have received this e-mail in error, please advise 
the sender immediately by reply e-mail and delete this message and any 
attachments without retaining a copy.

Any unauthorised copying, disclosure or distribution of the material in this 
e-mail is strictly forbidden.

_______________________________________________
Perl-Win32-Users mailing list
Perl-Win32-Users@listserv.ActiveState.com
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs

Reply via email to