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

I want to ‘hide’ widgets on a canvas and then make them visible again.
I have successfully done this before using widgets that have been placed using the grid manager.
I first tried
$wg_name->windowForget();
but this gave the following error
Tk::Error: Can't locate auto/Tk/Entry/windowForge.al in @INC (@INC contains:
C:/perl/perl5/lib C:/perl/perl5/site/lib .) at C:\canvas.pl line 306
Carp::croak at C:/perl/perl5/lib/Carp.pm line 269
more
(command bound to event)

I then tried
$wg_name->idForget();
which also failed in a similar manner giving
Tk::Error: Can't locate auto/Tk/Entry/idForget.al in @INC (@INC contains:
C:/perl/perl5/lib C:/perl/perl5/site/lib .) at C:\canvas.pl line 306
Carp::croak at C:/perl/perl5/lib/Carp.pm line 269
more
(command bound to event)

What should I do to make the widgets invisible?

I guess that I need to find the widget's position before I hide them so that I can make
them visible again.
I expected to have to use the ->createWindow option with the x and y of the widget.
I tried using ->cget(-x) and ->cget(-y) with both the widget and id name before the ->cget.
Both failed!
How do I find these positions and what exactly do I do to make the widgets visible again?

Replies are listed 'Best First'.
Re: Fogetting Tk Canvas widgets
by zentara (Cardinal) on Jun 06, 2008 at 14:03 UTC
    Updated example to show a canvas window hide technique

    The "widgets" on a canvas, are not widgets, they are "items" on a canvas. To make them disappear/reappear you have 2 choices. 1. is to move them way off the screen to some location out of view, like to -2000,-2000.

    2. You can use the tag lower/raise mechanism to hide them under a background. Canvas window items are special....you may need to move them, as they don't respond to raise/lower.

    #!/usr/bin/perl use warnings; use strict; use Tk; use Tk::JPEG; use Tk::PNG; #demonstrates need for subwidget method #on Scrolled Canvas, to use lower or raise my $mw = new MainWindow; my $canvas = $mw->Scrolled('Canvas', -bg => 'white', -xscrollincrement => 1, -yscrollincrement => 1, -confine => 1, -scrollbars => 'se', -width => 200, -height => 200, -closeenough =>3, -scrollregion => [ 0, 0, 500, 500 ], )->pack(qw/ -fill both -expand 1 -side top/); my $realcanvas = $canvas->Subwidget('scrolled'); $mw->Button(-text=>"Raise Bunny", -command => sub{ # $canvas->lower( 'bunny' ,'tux' ); # will cause error # need subwidget of the scrolled canvas $realcanvas->raise( 'bunny' ,'background' ); })->pack(); $mw->Button(-text=>"Lower Bunny", -command => sub{ $realcanvas->lower( 'bunny' ,'background' ); })->pack(); my $rect = $canvas->createRectangle(0,0,500, 500, -fill => 'orange', -tags => ['background'], ); my $bunny = $mw->Photo(-data => get_bunny() ); $canvas->createImage( 40, 40, -image => $bunny, -anchor => 'nw', -tags => ['bunny'], ); my $window = $canvas->Checkbutton(-text=> 'Foo'); my $win = $canvas->createWindow(20,20, -window=> $window, ); $canvas->move($win,-1000,-1000); #dx, dy $mw->Button(-text=>"Show Checkbox", -command => sub{ $canvas->move($win, 1000,1000 ); })->pack(); $mw->Button(-text=>"Hide Checkbox", -command => sub{ $canvas->move($win, -1000,-1000 ); })->pack(); # $canvas->lower( 'bunny' ,'background' ); # will cause error # need subwidget $realcanvas->lower( 'bunny' ,'background' ); MainLoop; sub get_bunny{ return 'iVBORw0KGgoAAAANSUhEUgAAAB4AAAAjEAIAAABcJvHFAAAACXBIWXMAAAsSAAALEgHS3 +X78AAAD F0lEQVR42u1YL+yqUBj1vfcLbhY3C44is8BIREYSG9FoNBqNkok2aFhp2BhJDWyadCZN/i +lOGxan jRdOuRsPxl/f+23vJKfX7x6+73znu5dK5RviV9QPDMMwDIPP7/f7/X6XTWU0Go1Go06n0+ +l0PM/z PC91CNu2bduWZVmW5bLpjsfj8XgcBEEQBJPJZDKZZAw0n8/n8zkCGYZhGIYgCIIgFEt3OB +wOh8OA gKZpmqZlDDedTqfTKRnO933f95GVer1er9fz0BVFURRFxCR3QfyMQfv9fr/fDyLgOI7jON +mo419k JUkMBoPBYJCRNBrxdrvdbrco6qvVarVaIWdFpQO/5tIcFBbE4nQ6nU6nJIpHjlGlEklTFE +VRFDIa T32/3+/3+3jqHMdxHBcfB2sK6HFFURRFeb1er9crfksoNUrr0GvUfxGfnA+FmX+QALDItG +LDA6O2 pQyCJFkPqxMDK2p9LodOAhQaLRjfoKRGo2wObl3G8PoDsA0Gb5Q5oonjfSNKTh96AOh+u9 +1ut1uS FuZrONPJ7bJ06tA9TDDsD6QkCnDltEDRkV1Q9AnENyuk8hcyChkkcZKo5uv1er1er3S6cA +PkFXSx MQodPrXFg2zTEsVANhO2JNdEmVo80ub7K/lSDHPyLkNaXrVarVar2W46LMuyLFsKaZ7neZ +4nvwFR NGKeGjYajUajkXz9z+RLn8/n8/ms/ANIQXq5XC6Xy/v9fr/fvw3p9Xq9Xq9VVVVV9fF4PB +6Pokhc r9fr9Vr6s6Lf4dNpbS6/exQA3BHDt/fkPl3wwT85wlcEcrCHZyHO1tmOSl95iGLcQN80Td +M0jTa1 LMuyLF3XdV03TdM0zWaz2Ww2Xdd1XRenDlDHgTbtvj/ykMZpDm/6LpfL5XLBmGi32+12G6 +Th5RAA Pne73W63iwfGYFosFovF4kOZrtVqtVoN16TD4XA4HPAAKDp5yZUkSZIk1GGz2Ww2m91ut9 +vt0Mof lcfxeDwej7PZbDaboRFbrVar1SJfIsLdYZfn8/l8Pue3y1zyiH9VAMFElb5Yp/+PcvAbH/ +25ox5S PYYAAAAASUVORK5CYII='; }

    I'm not really a human, but I play one on earth CandyGram for Mongo
      Thanks for that. I am going to try the move idea which I
      think I can do by setting a tag for all the items I want to move.
      I do not think that I need to know where the widget is originally
      if I simply use the neagitve values of the move to get them back again.
      However, for other reasons I would like to find the current position of them.
      I know where they are to begin with but I do move them.
      I could keep a record of their moves but it would be much simpler if I could find out where they are.
      As my original question showed I have tried various things but without success.
      Is it possible and if so how?
        You are probably looking for the $canvas->bbox() method. It has some quirks(like outline pixels being off), but it is usable.
        #!/usr/bin/perl use Tk; use strict; my $x=10; my $y=20; my $x1=30; my $y1=40; my $mw=tkinit; my $c=$mw->Canvas->pack; my $rect = $c->createRectangle($x,$y,$x1,$y1, -fill=>'red' ); print "rect-> $x $y $x1 $y1\n"; my ($bx,$by,$bx1,$by1)= $c->bbox($rect); print "bbox-> $bx $by $bx1 $by1\n"; MainLoop;

        I'm not really a human, but I play one on earth CandyGram for Mongo
Re: Fogetting Tk Canvas widgets
by Anonymous Monk on Jun 06, 2008 at 08:16 UTC
      I have now tried both packForget and gridForget.
      Neither gave an error message but sadly neither worked.
      Any suggestions?
      I was not sure what to try!
      However, I thought that the form of the forget varied with th type of 'packing'.
      Since the createWindow seemed to be the equivalent of packing for other than canvas based widget, it seemed as good a place and any.