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

Hi, i have a window with multiple frames. Once the user presses the delete button in the frame, i need to delete it and leave the remaining. For some reason i can't get the correct id. I know it can be deleted like: frame[0] -> destroy; but not based on the button pushed. Thanks for the help.
#!/usr/bin/perl -wd use Tk; $main = MainWindow->new(); # Container frame for dynamic subframes $fmain = $main->Frame(-borderwidth=>0)->pack(-side=>'top',-fill=>'both +'); # Dymanic subframes for ($a=0;$a<=1;$a++) { $frame[$a] = $fmain->Frame(-borderwidth => 0)->pack(-side=>'left'); $frame[$a] -> Label(-text => "Frame " . \$whichframe[$a] ) -> pack; $frame[$a] -> Button(-text => "Delete frame", -command => \&rmv ) -> p +ack; } MainLoop; sub rmv { #Need to delete the frame here. }

Replies are listed 'Best First'.
Re: Multiple frames
by choroba (Cardinal) on Aug 26, 2013 at 07:37 UTC
    When creating the button, you know what frame to delete. There are two ways how to pass parameters to callbacks: you can use a closure or use an array reference:
    # Closure - BROKEN! $frame[$a] -> Button(-text => "Delete frame", -command => sub { rmv( $ +frame[$a]) })->pack; # Array ref $frame[$a] -> Button(-text => "Delete frame", -command => [ \&rmv, $ +frame[$a] ] )->pack; } sub rmv { shift->destroy; }

    Update: Oops, closures do not work for global arrays. Fix:

    for (0 .. 5) { my $frame = $fmain->Frame(-borderwidth => 0)->pack(-side => 'left' +); $frame->Label( -text => "Frame " . \$whichframe[$_] )->pack; $frame->Button(-text => "Delete frame", -command => sub { rmv($frame) }, )->pack; }
    لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ
      Thank you!
        ok, so now i have added an entry widget to all the frames and using an array to store the values. it is always empty.
        #!/usr/bin/perl -d use Tk; $fmain = MainWindow -> new; $fmain -> title("Frame delete test"); @mycolor = qw(red green blue violet yellow black); for ( 0 .. 5 ) { my $frame = $fmain->Frame(-borderwidth => 10, -relief => 'groove', -b +ackground => $mycolor[$_]) ->pack(-side => 'top'); $lbl = $frame -> Label( -text => "Enter username: " ) ->pack; $ent = $frame -> Entry( -text => $username[$_] ) ->pack; $btn = $frame -> Button(-text => "Delete frame # " . $_, -command => sub { $val = $ent->cget('-text'); rmv_frm($frame,$val); } ) ->pack; } $ex = $fmain -> Button(-text => "Exit",-command => sub { exit } ) -> pack; MainLoop; sub rmv_frm { shift -> destroy; #$val_ref = $ent->cget('-text'); #$val = $$val_ref; $val = shift; print "You entered: $val\n"; # if no frames exist, need to "withdraw" fmain. $fmain -> withdraw if $fmain -> children == 0;