RE: need help with Tk: I could not figure the error

2009-09-03 Thread Brian Raven
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 = "#FF";
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=>'#00',
 -font=>['Arial',20,'bold'],
 -relief=>'groove',
 -anchor=>"c",
 -text=>$title)->pack( -side=>"top",
   -expand=>1,
   -fill=>'x' );

$top->Label( -borderwidth=>4,
 -bg=>$BGColor7,
 -fg=>'#00',
 -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, $fr

Re: need help with Tk: I could not figure the error

2009-09-02 Thread Daniel Burgaud
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.

This is wierd..

Dan



On Thu, Sep 3, 2009 at 12:05 AM, Daniel Burgaud  wrote:

> Hi All,
>
> Here is the message I got after using "use warnings;" and "use
> diagnostics;".
>
> Variable "$number" will not stay shared at x.pl line 36 (#1)
> (W closure) An inner (nested) named subroutine is referencing a
> lexical variable defined in an outer subroutine.
>
> When the inner subroutine is called, it will probably see the value of
> the outer subroutine's variable as it was before and during the *first*
> call to the outer subroutine; in this case, after the first call to the
> outer subroutine is complete, the inner and outer subroutines will no
> longer share a common value for the variable.  In other words, the
> variable will no longer be shared.
>
> Furthermore, if the outer subroutine is anonymous and references a
> lexical variable outside itself, then the outer and inner subroutines
> will never share the given variable.
>
> This problem can usually be solved by making the inner subroutine
> anonymous, using the sub {} syntax.  When inner anonymous subs that
> reference variables in outer subroutines are called or referenced, they
> are automatically rebound to the current values of such variables.
>
> Variable "$flag" will not stay shared at x.pl line 40 (#1)
> Variable "%t" will not stay shared at x.pl line 48 (#1)
>
> Apparently, I dont understand the above and what it meant. It appears that
> the variables inside the subroutine is being reused or wrongly used.
> because i
> am now getting this error:
>
> Tk::Error: Can't call method "configure" on an undefined value at x.pl line
> 48.
>  Tk callback for .toplevel.frame.button5
>  Tk::__ANON__ at C:/Perl/lib/Tk.pm line 252
>  Tk::Button::butUp at C:/Perl/lib/Tk/Button.pm line 111
>  
>  (command bound to event)
>
> Line 48 is referring to:
> $t{LZ}->configure(-text=>$number);
>
> 1st time it runs, no problem; 2nd time it gave that error as if the
> variable
> $t{LZ} does not exists.
>
>
> Any idea where i am doing wrong?
>
> BTW. I cannot use withdraw/iconfy because the Keypress event will be used
> on another
> TopLevel and thus i have to destroy this toplevel everytime it leaves.
>
> Dan
>
>
>
>
> On Wed, Sep 2, 2009 at 11:13 PM, Brian Raven  wrote:
>
>> From: perl-win32-users-boun...@listserv.activestate.com
>> [mailto:perl-win32-users-boun...@listserv.activestate.com] On Behalf Of
>> Daniel Burgaud
>> Sent: 02 September 2009 15:27
>> To: Perl-Win32-Users
>> Subject: need help with Tk: I could not figure the error
>>
>> > I have this test script below.
>> >
>> > A toplevel containing a button that invokes another toplevel.
>> > The first time I invoke this second window, all works fine and returns
>> properly without error.
>> >
>> > however, when I reenter again (clicking on "Get Number" button) I get
>> this error message.
>> >
>> > Tk::Error: not a Tk object
>> >  Tk::die_with_trace at x.pl line 46
>> >  main::AddNumber at x.pl line 66
>> >  main::__ANON__ at C:/Perl/lib/Tk.pm line 252
>> >  (eval) at C:/Perl/lib/Tk.pm line 252
>> >  Tk::__ANON__ at C:/Perl/lib/Tk/Button.pm line 111
>> >  Tk::Button::butUp at x.pl line 79
>> >  (eval) at x.pl line 79
>> >  main::GetNumber at x.pl line 17
>> >  main::__ANON__ at C:/Perl/lib/Tk.pm line 252
>> >  (eval) at C:/Perl/lib/Tk.pm line 252
>> >  Tk::__ANON__ at C:/Perl/lib/Tk/Button.pm line 111
>> >  Tk::Button::butUp at x.pl line 20
>> >  (eval) at x.pl line 20
>> >  Tk callback for .toplevel.frame.button5
>> >  Tk::__ANON__ at C:/Perl/lib/Tk.pm line 252
>> >  Tk::Button::butUp at C:/Perl/lib/Tk/Button.pm line 111
>> >  
>> >  (command bound to event)
>> >
>> > Hoping for help.
>> >
>> > thanks.
>> > Dan
>> >
>> >
>> >
>> >
>> 
>> 
>> > use strict;
>>
>> perl will give you a clue if you add "use warnings;" here. It will even
>> give

Re: need help with Tk: I could not figure the error

2009-09-02 Thread Daniel Burgaud
Hi All,

Here is the message I got after using "use warnings;" and "use
diagnostics;".

Variable "$number" will not stay shared at x.pl line 36 (#1)
(W closure) An inner (nested) named subroutine is referencing a
lexical variable defined in an outer subroutine.

When the inner subroutine is called, it will probably see the value of
the outer subroutine's variable as it was before and during the *first*
call to the outer subroutine; in this case, after the first call to the
outer subroutine is complete, the inner and outer subroutines will no
longer share a common value for the variable.  In other words, the
variable will no longer be shared.

Furthermore, if the outer subroutine is anonymous and references a
lexical variable outside itself, then the outer and inner subroutines
will never share the given variable.

This problem can usually be solved by making the inner subroutine
anonymous, using the sub {} syntax.  When inner anonymous subs that
reference variables in outer subroutines are called or referenced, they
are automatically rebound to the current values of such variables.

Variable "$flag" will not stay shared at x.pl line 40 (#1)
Variable "%t" will not stay shared at x.pl line 48 (#1)

Apparently, I dont understand the above and what it meant. It appears that
the variables inside the subroutine is being reused or wrongly used. because
i
am now getting this error:

Tk::Error: Can't call method "configure" on an undefined value at x.pl line
48.
 Tk callback for .toplevel.frame.button5
 Tk::__ANON__ at C:/Perl/lib/Tk.pm line 252
 Tk::Button::butUp at C:/Perl/lib/Tk/Button.pm line 111
 
 (command bound to event)

Line 48 is referring to:
$t{LZ}->configure(-text=>$number);

1st time it runs, no problem; 2nd time it gave that error as if the variable
$t{LZ} does not exists.


Any idea where i am doing wrong?

BTW. I cannot use withdraw/iconfy because the Keypress event will be used on
another
TopLevel and thus i have to destroy this toplevel everytime it leaves.

Dan



On Wed, Sep 2, 2009 at 11:13 PM, Brian Raven  wrote:

> From: perl-win32-users-boun...@listserv.activestate.com
> [mailto:perl-win32-users-boun...@listserv.activestate.com] On Behalf Of
> Daniel Burgaud
> Sent: 02 September 2009 15:27
> To: Perl-Win32-Users
> Subject: need help with Tk: I could not figure the error
>
> > I have this test script below.
> >
> > A toplevel containing a button that invokes another toplevel.
> > The first time I invoke this second window, all works fine and returns
> properly without error.
> >
> > however, when I reenter again (clicking on "Get Number" button) I get
> this error message.
> >
> > Tk::Error: not a Tk object
> >  Tk::die_with_trace at x.pl line 46
> >  main::AddNumber at x.pl line 66
> >  main::__ANON__ at C:/Perl/lib/Tk.pm line 252
> >  (eval) at C:/Perl/lib/Tk.pm line 252
> >  Tk::__ANON__ at C:/Perl/lib/Tk/Button.pm line 111
> >  Tk::Button::butUp at x.pl line 79
> >  (eval) at x.pl line 79
> >  main::GetNumber at x.pl line 17
> >  main::__ANON__ at C:/Perl/lib/Tk.pm line 252
> >  (eval) at C:/Perl/lib/Tk.pm line 252
> >  Tk::__ANON__ at C:/Perl/lib/Tk/Button.pm line 111
> >  Tk::Button::butUp at x.pl line 20
> >  (eval) at x.pl line 20
> >  Tk callback for .toplevel.frame.button5
> >  Tk::__ANON__ at C:/Perl/lib/Tk.pm line 252
> >  Tk::Button::butUp at C:/Perl/lib/Tk/Button.pm line 111
> >  
> >  (command bound to event)
> >
> > Hoping for help.
> >
> > thanks.
> > Dan
> >
> >
> >
> >
> 
> 
> > use strict;
>
> perl will give you a clue if you add "use warnings;" here. It will even
> give some advice if you make it "use diagnostics;".
>
> > use Tk;
> > ...
>
> 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
>
___
Perl-Win32-Users mailing list
Perl-Win32-Users@listserv.ActiveState.com
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs


RE: need help with Tk: I could not figure the error

2009-09-02 Thread Brian Raven
From: perl-win32-users-boun...@listserv.activestate.com
[mailto:perl-win32-users-boun...@listserv.activestate.com] On Behalf Of
Daniel Burgaud
Sent: 02 September 2009 15:27
To: Perl-Win32-Users
Subject: need help with Tk: I could not figure the error

> I have this test script below.
> 
> A toplevel containing a button that invokes another toplevel.
> The first time I invoke this second window, all works fine and returns
properly without error.
> 
> however, when I reenter again (clicking on "Get Number" button) I get
this error message.
> 
> Tk::Error: not a Tk object
>  Tk::die_with_trace at x.pl line 46
>  main::AddNumber at x.pl line 66
>  main::__ANON__ at C:/Perl/lib/Tk.pm line 252
>  (eval) at C:/Perl/lib/Tk.pm line 252
>  Tk::__ANON__ at C:/Perl/lib/Tk/Button.pm line 111
>  Tk::Button::butUp at x.pl line 79
>  (eval) at x.pl line 79
>  main::GetNumber at x.pl line 17
>  main::__ANON__ at C:/Perl/lib/Tk.pm line 252
>  (eval) at C:/Perl/lib/Tk.pm line 252
>  Tk::__ANON__ at C:/Perl/lib/Tk/Button.pm line 111
>  Tk::Button::butUp at x.pl line 20
>  (eval) at x.pl line 20
>  Tk callback for .toplevel.frame.button5
>  Tk::__ANON__ at C:/Perl/lib/Tk.pm line 252
>  Tk::Button::butUp at C:/Perl/lib/Tk/Button.pm line 111
>  
>  (command bound to event)
> 
> Hoping for help.
> 
> thanks.
> Dan
> 
> 
> 
>


> use strict;

perl will give you a clue if you add "use warnings;" here. It will even
give some advice if you make it "use diagnostics;".

> use Tk;
> ...

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


need help with Tk: I could not figure the error

2009-09-02 Thread Daniel Burgaud
I have this test script below.

A toplevel containing a button that invokes another toplevel.
The first time I invoke this second window, all works fine and returns
properly without error.

however, when I reenter again (clicking on "Get Number" button) I get this
error message.

Tk::Error: not a Tk object
 Tk::die_with_trace at x.pl line 46
 main::AddNumber at x.pl line 66
 main::__ANON__ at C:/Perl/lib/Tk.pm line 252
 (eval) at C:/Perl/lib/Tk.pm line 252
 Tk::__ANON__ at C:/Perl/lib/Tk/Button.pm line 111
 Tk::Button::butUp at x.pl line 79
 (eval) at x.pl line 79
 main::GetNumber at x.pl line 17
 main::__ANON__ at C:/Perl/lib/Tk.pm line 252
 (eval) at C:/Perl/lib/Tk.pm line 252
 Tk::__ANON__ at C:/Perl/lib/Tk/Button.pm line 111
 Tk::Button::butUp at x.pl line 20
 (eval) at x.pl line 20
 Tk callback for .toplevel.frame.button5
 Tk::__ANON__ at C:/Perl/lib/Tk.pm line 252
 Tk::Button::butUp at C:/Perl/lib/Tk/Button.pm line 111
 
 (command bound to event)

Hoping for help.

thanks.
Dan




use strict;
use Tk;
use Time::HiRes qw(time usleep);
my $BGColor0 = "#D8D0C8";
my $BGColor1 = "#D0D0D0";
my $BGColor2 = "#808080";
my $BGColor3 = "#5090C0";
my $BGColor4 = "#4070A0";
my $BGColor5 = "#80C080";
my $BGColor6 = "#408040";
my $BGColor7 = "#FF";
my $BGColor8 = "#E0E0E0";
my $BGColor9 = "#FF8080";

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

while(1) {
$mw->update;
usleep 5000;
}


sub GetNumber {
my $title = shift;
my %t;
my $number = 0;
my $flag = 1;

sub AddNumber {
my $key = shift;
if ('0123456789' =~ $key) {
$number .= $key;
} elsif ($key eq 'period' && $number !~ /\./) {
$number .= '.';
} elsif ($key eq 'Return') {
$flag = 0;
} elsif ($key eq 'Escape') {
$number = '';
$flag = 0;
} elsif ($key eq 'BackSpace') {
chop($number);
chop($number) if substr($number,-1) eq '.';
}
$t{LZ}->configure(-text=>$number);
}
sub Keyboard {
my $widget = shift;
my $e = $widget->XEvent;# get event object
my $key = $e->K;
AddNumber($key);
}

$t{L0} = $mw->Toplevel(-title=>$title);
$t{L0}->resizable(0,0);
   $t{L0}->transient($t{L0}->Parent->toplevel);
$t{LT}= $t{L0}->Label( -borderwidth=>2, -bg=>$BGColor3,
-fg=>'#00', -font=>['Arial',20,'bold'], -relief=>'groove', -anchor=>"c",
-text=>$title)->pack( -side=>"top",  -expand=>1, -fill=>'x', );
$t{LZ}= $t{L0}->Label( -borderwidth=>4, -bg=>$BGColor7,
-fg=>'#00', -font=>['Arial',40,'bold'], -relief=>'groove', -anchor=>"e",
)->pack( -side=>"top",  -expand=>1, -fill=>'x', );
$t{L1}= $t{L0}->Frame( -borderwidth=>2,  )->pack( -side=>'left',
-expand=>1, -fill=>'both');

$t{L1}->Button( -borderwidth=>3, -bg=>$BGColor3,
-activebackground=>$BGColor4, -width=>4, -height=>1, -text => "7",
-font=>['Courier',30,'bold'], -command => sub{AddNumber('7')},
)->grid(
$t{L1}->Button( -borderwidth=>3, -bg=>$BGColor3,
-activebackground=>$BGColor4, -width=>4, -height=>1, -text => "8",
-font=>['Courier',30,'bold'], -command => sub{AddNumber('8')},),
$t{L1}->Button( -borderwidth=>3, -bg=>$BGColor3,
-activebackground=>$BGColor4, -width=>4, -height=>1, -text => "9",
-font=>['Courier',30,'bold'], -command => sub{AddNumber('9')},),
-sticky=>'news');
$t{L1}->Button( -borderwidth=>3, -bg=>$BGColor3,
-activebackground=>$BGColor4, -width=>4, -height=>1, -text => "4",
-font=>['Courier',30,'bold'], -command => sub{AddNumber('4')},
)->grid(
$t{L1}->Button( -borderwidth=>3, -bg=>$BGColor3,
-activebackground=>$BGColor4, -width=>4, -height=>1, -text => "5",
-font=>['Courier',30,'bold'], -command => sub{AddNumber('5')},),
$t{L1}->Button( -borderwidth=>3, -bg=>$BGColor3,
-activebackground=>$BGColor4, -width=>4, -height=>1, -text => "6",
-font=>['Courier',30,'bold'], -command => sub{AddNumber('6')},),
-sticky=>'news');
$t{L1}->Button( -borderwidth=>3, -bg=>$BGColor3,
-activebackground=>$BGColor4, -width=>4, -height=>1, -text => "1",
-font=>['Courier',30,'bold'], -command => sub{AddNumber('1')},
)->grid(
$t{L1}->Button( -borderwidth=>3, -bg=>$BGColor3,
-activebackground=>$BGColor4, -width=>4, -height=>1, -text => "2",
-font=>['Courier',30,'bold'], -command => sub{AddNumber('2')},),
$t{L1}->Button( -borderwidth=>3, -bg=>$BGColor3,
-activebackground=>$BGColor4, -width=>4, -height=>1, -text => "3",
-font=>['Courier',30,'bold'], -command => sub{AddNumber('3')},),
-sticky=>'news');
$t{L1}->Button( -borderwidth=>3, -bg=>$BGColor3,
-activebackground=>$BGColor4, -width=>4, -height=>1, -text => "0",
-font=>['Courier',30,'bold'], -command => sub{AddNumber('0')},
)->grid(
$t{L1}->Button( -b