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

I am trying to create a Perl program (Perl Tk GUI) that runs different scripts based on what users choose out of a menu at the top. The scripts output text progress and feedback based on records that the script processed into a Scrolled widget/element. I want to be able to forget/destroy/delete the widget when I move to a new option in the menu so I can create a fresh one to output text from the next script the user will run.

my $mainFrame = $mw->Frame()->pack(-side=>'top'); my $tx = $mainFrame->Scrolled(qw/Text -font normal -width 73 -height 15 -wrap word -scrollbars e/); $tx->pack; tie *STDOUT, 'Tk::Text', $tx; #script is called, runs, outputs to Scrolled above, user chooses new o +ption and sub clear() is called: sub clear{ $mainFrame ->destroy(); $tx ->pack('forget'); }

I want the $tx widget to disappear/clear off the screen

I have tried multiple things like forget, destroy, delete and anything else I could find on this site and around the interwebs. Some of them don't throw errors at all, but when I go to run a different script, the Scrolled widget/element will not clear from the screen so the new one shows up below the old one. I am relatively new to Perl GUI programming (this is my first GUI with Perl and I am trying to learn it as I go) so go easy on me

</code>

Replies are listed 'Best First'.
Re: Perl Tk Forgetting a Widget
by zentara (Cardinal) on Oct 14, 2011 at 12:54 UTC
    You are close, your use of packForget is wrong. There is no pack('forget'). Also you need to watch your memory when destroying widgets, Tk has a nasty habit of leaving refcounts around which cause memory gains over time. So try to reuse the $tx variable. Here is how I would do it. Don't destroy the Frame, as that causes an unpleasant window size change.
    #!/usr/bin/perl use warnings; use strict; use Tk; my $mw = MainWindow->new; my $mainFrame = $mw->Frame()->pack(-side=>'top'); my $tx; # reuse global to prevent memory gains rebuild(); #setup first use # script is called, runs, outputs to Scrolled above, user # chooses new option and sub clear() is called: my $button = $mw->Button(-text=> 'Clear', -command => \&clear )->pack(); my $button1 = $mw->Button(-text=> 'Rebuild', -command => \&rebuild )->pack(); MainLoop; sub clear{ #$mainFrame ->destroy(); # don't, causes screen jitter $tx->packForget; # $tx ->pack('forget'); #wrong usage #clean out a top level # my @w = $tl->packSlaves; # foreach (@w) { $_->packForget; } } sub rebuild{ $tx = $mainFrame->Scrolled(qw/Text -font normal -width 73 -height 15 -wrap word -scrollbars e/); $tx->pack; tie *STDOUT, 'Tk::Text', $tx; print "foobar!".time."\n"; }

    I'm not really a human, but I play one on earth.
    Old Perl Programmer Haiku ................... flash japh

      I agree re Tk's nasty habits. I don't understand the desire to destroy/recreate or forget/repack. Why not just clear all the text from the widget?

      sub clear { $tx->delete('1.0','end'); }
        Why not just clear all the text from the widget?

        So he could rebuild another page for that Frame, perhaps a Canvas with a chart on it?


        I'm not really a human, but I play one on earth.
        Old Perl Programmer Haiku ................... flash japh
Re: Perl Tk Forgetting a Widget
by Khen1950fx (Canon) on Oct 14, 2011 at 03:04 UTC
    Using a simple example of an exit callback:
    #!/usr/bin/perl use strict; use warnings; use Tk; my $mw = MainWindow->new; fill_window($mw, 'Main'); my $top1 = $mw->Frame; fill_window($top1, 'First Frame'); my $tx = $mw->Scrolled('Text', -font => 'normal', -width => '73', -height => '15', -wrap => 'word', -scrollbars => 'e'); $tx->pack; tie *STDOUT, 'Tk::Text', $tx; MainLoop; sub fill_window{ my ($window, $header) = @_; $window->Label(-text => $header)->pack; $window->Button( '-text' => 'forget', '-command' => [$mw => 'destroy'] )->pack('-side' => 'right'); }
Re: Perl Tk Forgetting a Widget
by priyaviswam (Sexton) on Oct 14, 2011 at 07:31 UTC

    Make the variable $tx as global and try destroy I have tried similar scenario with the checkbuttons it worked.