Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change

Perl/Tk widget removal problem...

by jdtoronto (Prior)
on Aug 29, 2003 at 17:33 UTC ( [id://287771] : perlquestion . print w/replies, xml ) Need Help??

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

Esteemed Monks,

In the following code a button is placed in a grid inside a frame inside a NoteBook tab.

sub doFileImportUi { my ($pg, $dbh) = @_; $pg->Label(-text => 'File', -width => '10')->grid( $pg->LabEntry(-width => '30', -textvariable => \$state->{ImpFi +le}), $pg->Button(-text => 'Browse', -command => [ \&getImportFile, $ +pg, $dbh], -width => '10')); $pg->Label(-text => 'DataSource', -justify => 'right', -width => ' +20') ->grid(my $ds_list = $pg->BrowseEntry(-variable => \$state +->{dsSrcName}, -browsecmd => \&doGetDatasource, -listcmd => [ \&doLoa +dDs, $pg, $dbh ], -width => '20'), -sticky => 'w'); my $gbtn = $pg->Button(-text => 'Next Phase')->grid(); $gbtn->configure( -command => [ \&doImportFile, $pg, $dbh, $gbtn +]); my @listname = &doLoadDs($pg, $dbh); $ds_list->insert('end', @listname); }
When I click on that button and go to the doImportFile() sub I want to remove the button. According to the grid manpage it is possible, but if I use this code, which seems plausible according to the manpage:
Then I get the error:
--- Begin Traceback --- Failed to AUTOLOAD 'Tk::Frame::gridRemove' at line 437 Carp::croak at K:/Perl/lib/ line 191 Tk::Widget::__ANON__ at K:/Perl/site/lib/Tk/ line 338 main::doImportFile at line 437 [\&main::doImportFile,{},{},{}] Tk callback for .notebook.page4.button1 Tk::__ANON__ at K:/Perl/site/lib/ line 228 Tk::Button::butUp at K:/Perl/site/lib/Tk/ line 111 (command bound to event)
Does any one have a suggestion to offer about how to remove the button from the window?


Replies are listed 'Best First'.
Re: Perl/Tk widget removal problem...
by batkins (Chaplain) on Aug 29, 2003 at 17:49 UTC
    I don't have too much experience with the grid manager, but I think the problem may be that $pg was never actually gridded in. Try saving the wdigets to variables and then calling gridRemove on them. For example:
    sub doFileImportUi { ... my $lbl1 = $pg->Label(-text => 'File', -width => '10'); my $entr1 = $pg->LabEntry(-width => '30', -textvariable => \$state +->{ImpFile}), $pg->Button(-text => 'Browse', -command => [ \&getImpor +tFile, $pg, $dbh], -width => '10'); $lb1->grid($entr1); ... }
    Then later on, do
    Of course, you'd want to use more meaningful variable names than those, but I think that should do the trick.
    it says she can do math, but will she recognize 8 / 0?

    We can only hope they've put in those safeguards.

    Worst case scenario: She succeeds in dividing by zero, and suddenly little Tiphany-Amber's bedroom becomes the center of a howling vortex of nonspace, frying the neighborhood with sparkling discharges of zero-point energy.

    - slashdot
Re: Perl/Tk widget removal problem...
by bbfu (Curate) on Aug 29, 2003 at 18:48 UTC

    Use gridForget() instead. You'll lose your configuration options, but it seems to work.

    And some sample code, just because:

    #!/usr/bin/winperl use warnings; use strict; use Tk; my $mw = MainWindow->new(); $mw->Label(-text => 'Do it')->grid(); my $btn; $btn = $mw->Button( -text => 'Click me', -command => sub { $btn->gridForget() }, )->grid(); MainLoop;

    Black flowers blossom
    Fearless on my breath

      Thanks batkin and bbfu.

      Two valuable suggestions, thank you!

      I solved my problem by making the GUI look even cleaner, I put the upper part of the thing in a frame called $upp and the button in $lower, then I add to $upper as needed and the button stays below and gets re-configured every time.

      Just tested it, looks nice and works well with less code.


Re: Perl/Tk widget removal problem...
by converter (Priest) on Aug 29, 2003 at 20:04 UTC

    I was just poking around in the Tk source (I think I'll be able to grok Lex Rex before I understand the Tk source) and it looks like there's no support for gridRemove in the code where I'd expect to find it. Maybe it was removed, or never added in the first place?

    In Tk/ (I THINK this is part of the dispatch mechanism):

    sub grid { local $SIG{'__DIE__'} = \&Carp::croak; my $w = shift; if (@_ && $_[0] =~ /^(?:bbox|columnconfigure|configure|forget|info|lo +cation|propagate|rowconfigure|size|slaves)$/x) { my $opt = shift; Tk::grid($opt,$w,@_); } else { # Two things going on here: # 1. Add configure on the front so that we can drop leading '-' Tk::grid('configure',$w,@_); # 2. Return the widget rather than nothing return $w; } }

    Note that a direct call to &Tk::grid with the 'remove' argument works:

    $ perl -MTk -e '$m=tkinit; $f=$m->Frame->pack; $b=$f->Button(-text=>"F +oo")->grid; $m->after(750,sub{Tk::grid("remove",$b)}); MainLoop'

    This patch to Tk/ version 3.080 (Tk 800.024) seems to fix the problem for me:


      More than 10 years later (Tk/ version 4.035) and the bug (inconsistency between documentation and implementation) still exists. Fortunately, your patch still works, except for the line numbers.

      I have tested minimally and have no idea why this method is not supported. Maybe they have left it out for good reason that I am, thus far, blissfully unaware of.