Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

Undefined Button method??

by eoin (Monk)
on Feb 18, 2004 at 16:20 UTC ( [id://329945]=perlquestion: print w/replies, xml ) Need Help??

eoin has asked for the wisdom of the Perl Monks concerning the following question:

I started a Tk calculator script a day or two ago and I nearly have it. I've already posted here but I feel that this problem could be better addressed on its own.
I am getting this error from the script
Uncaught exception from user code: Can't call method "Button" on an undefined value at C:\Documents and S +ettings\Eoin\Desktop\calc.pl line 52.
From what I understand from the error is that it is saying that  $rows[$r] is undefined. Where as @rows is quite clearly defined, as is $r.

UPDATE: I've discovered that the error is being caused by having the function button chars (i.e. * n* - \ + =) in the array for $i
for my $i ( qw/ 7 8 9 * n* 4 5 6 - \ 1 2 3 + = 0 . C / )
Now i'm really confused!!


Heres the rest of it.
my $mw = new MainWindow(-title => 'Calc'); $mw->geometry("300x300"); my $topframe = $mw->Frame(-height => '60', -width => '300')->pack(-sid +e => 'top', -expand => '0', -fill => 'x' +); my $btmframe = $mw->Frame(-height => '225', -width => '300',)->pack(-s +ide => 'left', -expand => '1', -fill => +'both'); push @rows, $btmframe->Frame()->pack( -expand => 1, -fill => 'both', - +side => 'top') for (0..3); my $display = $topframe->Entry(-justify => 'right', -state => 'disabled', -textvariable => \$calc) ->pack(-expand => '1', -fill => 'x', -pady => 30, -padx => 20, -side => 'right'); $mw->bind("<KeyRelease>" , sub { &keypress } ); my $r = 0; for my $i ( qw/ 7 8 9 * n* 4 5 6 - \ 1 2 3 + = 0 . C / ) { if($i eq '+' || $i eq '=') { $h = 2; } ########LINE 52 BELOW################ $button{$i} = $rows[$r]->Button(-text => "$i", -width => '3', -height => "$h", -command => sub { &btnpress($i) }) ->pack(-expand => 1, -fill => 'both', -padx => 2, -pady => 2, -side => 'left', -ipadx => 5, -ipady => 5); $w++; $h = 1; if($w > 2){$w = 0; $r++;} } MainLoop;
If anyone has any ideas on whats causing the problem, feel free to let me know. All and any help is greatly appriciated. :)

Cheers, Eoin...

Replies are listed 'Best First'.
Re: Undefined Button method??
by antirice (Priest) on Feb 18, 2004 at 17:30 UTC
    if($w > 2){$w = 0; $r++;}

    Perhaps $r should change when $w > 4?

    antirice    
    The first rule of Perl club is - use Perl
    The
    ith rule of Perl club is - follow rule i - 1 for i > 1

      God, I don't know how I missed that!!!
      I'll have to wake up next time I think of posting a question. Thanks

      Cheers, Eoin...
Re: Undefined Button method??
by zentara (Archbishop) on Feb 18, 2004 at 17:39 UTC
    First, always post full code, otherwise we HAVE TO GUESS at what you are doing wrong. In the code you posted, half of your variables are uninitialized, so I had to improvise. Second, I thought you were going to switch to grid, which is better suited for this. So that said, I've modified your code to work, but without grid, all your buttons end up in one row. Either switch to grid, or make a frame for each row, and when you make your buttons, switch to the next frame when your $counter goes over 4 or whatever. I think your original problem came from the way you setup your
    qw/ 7 8 9 * n* 4 5 6 - \ 1 2 3 + = 0 . C / ) {
    and it was getting an undef value in there.

    I'm not going to do your project for you. The code below is a patched up version of your code, which runs. Getting the rows setup right is up to you. Switch to grid, or setup separate frames for your rows of buttons.

    #!/usr/bin/perl use Tk; use warnings; use strict; my %button; my $calc = 0; my $mw = new MainWindow( -title => 'Calc' ); $mw->geometry("300x300"); my $topframe = $mw->Frame( -height => '60', -width => '300' ) ->pack( -side => 'top', -expand => '0', -fill => 'x' ); my $btmframe = $mw->Frame( -height => '225', -width => '300', ) ->pack( -side => 'left', -expand => '1', -fill => 'both' ); push my @rows, $btmframe->Frame()->pack( -expand => 1, -fill => 'both', -side => 't +op' ) for ( 0 .. 3 ); my $display = $topframe->Entry( -justify => 'right', -state => 'disabled', -textvariable => \$calc )->pack( -expand => '1', -fill => 'x', -pady => 30, -padx => 20, -side => 'right' ); $mw->bind( "<KeyRelease>", sub { &keypress } ); my $r = 1; my $h = 1; my $w = 1; for my $i (qw/ 7 8 9 * n* 4 5 6 - \ 1 2 3 + = 0 . C / ) { if ( $i eq '+' || $i eq '=' ) { $h = 2; } ########LINE 52 BELOW################ $button{$i} = $mw->Button( -text => "$i", -width => '1', -height => "$h", # -command => sub { &btnpress($i) } )->pack( -expand => 1, -fill => 'both', -padx => 2, -pady => 2, -side => 'left', -ipadx => 5, -ipady => 5 ); $w++; $h = 1; if ( $w > 2 ) { $w = 0; $r++; } } MainLoop;

    I'm not really a human, but I play one on earth. flash japh
      I tried out grid and it worked for the most part but I wanted to get the buttons to resize if I resized the window. I couldn't figure out how to do this with grid. JamesNC suggested a way of using pack to get the buttons right, the seperate frames, just as you said. And that worked nicely.
      Thanks for your advice any way. If you know how to get the buttons to expand I'd be more than happy to give grid a try again.

      Cheers, Eoin...
Re: Undefined Button method??
by graff (Chancellor) on Feb 19, 2004 at 03:27 UTC
    It looks like antirice's reply pinpoints your initial problem: you define 4 frame widgets --  @row[0..3] -- and your arrangement of values for $i is such that you appear to want 5 elements on each of the first three rows. But then you increment $r (row counter) after every third element (not every fifth one), which means $r will increment beyond 3.

    As for your update about having a problem because you're assigning values like "*" and "." and "+" etc to $i -- that's a red herring. Those assignments are perfectly fine. Consider:

    #!/usr/bin/perl @w = qw/a b + * \ x y = . - z/; print join(" : ", @w),$/; for $i ( @w ) { $h{$i} = " okay\n" } print join "", %h; __OUTPUT__ a : b : + : * : \ : x : y : = : . : - : z + okay a okay - okay z okay * okay x okay = okay \ okay b okay y okay . okay
    The "qw" operator even disarms the special meaning of backslash, and passes it through as a literal string.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://329945]
Approved by kutsu
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others chilling in the Monastery: (5)
As of 2024-04-23 19:42 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found