in reply to Re^6: perltk autoresize following users resize
in thread perltk autoresize following users resize

I've run your code, and read your explanation, but I "think" you are misunderstanding what you can do in resizing the widgets. The mainwindow will automatically pack itself to the smallest size that will show everything. That is what you get when you first run your program. If at that point, if I try to make the y height smaller, the Exit button will disappear. If I make y bigger, no problem. The same applies to your repacking. If there is not enough room for everything, the last packed widget will be lopped off, and the packer won't automagically shrink the first packed widgets to accomodate everything. You can see this by setting the geometry a bit small, the Exit button will be lopped off. You probably can make some more room by cutting the padding on your frames from 5 to 1.
$goMainWindow = new MainWindow; $goMainWindow->geometry('200x300'); #Exit is lopped off

You have a couple of options as I see it.

1. Set a minimum size on Resizing your window. This can be done by setting no geometry at first, letting pack fill to the minimum size, grab that size and set that as a minimum.

# at ther end of your build_gui sub $goMainWindow->idletasks; my $w = $goMainWindow->reqwidth; my $h = $goMainWindow->reqheight; print "$w $h\n"; $goMainWindow->minsize($w,$h);
that will prevent them making the window smaller than what is required to show everything.

2. You could put your repacked stuff into a scrolled Pane. Leave the Exit button on the mainwindow.

#!/usr/bin/perl use strict; use Tk; require Tk::Pane; our ($goMainWindow); our (%ghGuiObjs); our (%ghGuiCBVars); $| = 1; &main(); sub main { buildGui(); MainLoop; } #end sub main sub updateA { if ( $ghGuiCBVars{"nEnableFrameA"} == 1 ) { $ghGuiObjs{"oContainerA"}->pack( -expand => '1', -fill => 'both', -pady => '5', ); } else { $ghGuiObjs{"oContainerA"}->packForget(); } } sub updateB { if ( $ghGuiCBVars{"nEnableFrameB"} == 1 ) { $ghGuiObjs{"oContainerB"}->pack( -expand => '1', -fill => 'both', -pady => '5', ); } else { $ghGuiObjs{"oContainerB"}->packForget(); } } sub buildGui { $goMainWindow = new MainWindow; my $mf = $goMainWindow->Scrolled('Pane', -scrollbars => 'osoe', )->pack( -expand => '1', -fill => 'both', -pady => '5', ); my ($oLabel) = $mf->Label( -text => "This is my example", )->pack( -padx => '5', -pady => '5', -expand => '1', -fill => 'x', ); my ($oCbA) = $mf->Checkbutton( -text => 'Enable A', -variable => \$ghGuiCBVars{"nEnableFrameA"}, -command => \&updateA, -anchor => 'w', ); $ghGuiCBVars{"nEnableFrameA"} = 1; my ($oFrameA) = $mf->Labelframe( -labelwidget => $oCbA, )->pack( -padx => '5', -expand => '1', -fill => 'both', ); my ($oContainerFrameA) = $oFrameA->Frame( )->pack( -expand => '1', -fill => 'both', -pady => '5', ); $ghGuiObjs{"oContainerA"} = $oContainerFrameA; my ($oLbA) = $oContainerFrameA->Listbox( -relief => 'groove', -borderwidth => '5', -height => '5', )->pack( -fill => 'both', -expand => '1', ); my ($oCbB) = $mf->Checkbutton( -text => 'Enable B', -variable => \$ghGuiCBVars{"nEnableFrameB"}, -command => \&updateB, -anchor => 'w', ); $ghGuiCBVars{"nEnableFrameB"} = 1; my ($oFrameB) = $mf->Labelframe( -labelwidget => $oCbB, )->pack( -padx => '5', -expand => '1', -fill => 'both', ); my ($oContainerFrameB) = $oFrameB->Frame( )->pack( -expand => '1', -fill => 'both', -pady => '5', ); $ghGuiObjs{"oContainerB"} = $oContainerFrameB; my ($oLbB) = $oContainerFrameB->Listbox( -relief => 'groove', -borderwidth => '5', -height => '5', )->pack( -fill => 'both', -expand => '1', ); my ($oExit) = $goMainWindow->Button(-text => 'Exit', -command => sub{exit}, )->pack( -padx => '5', -pady => '5', -side => 'bottom', ); }
One final word, in your original script, when you repacked, you didn't give the expand and fill options.

So, I don't know what you expect of the resizer. If you make the mainwindow smaller than what is needed to display everything, something will get lopped off..... widgets don't act like scalable fonts. If you truly wanted scalable widgets, you could make your program on a Canvas-type widget that supports group scaling.....but that is alot more work.

Of course, my view of things may be limited to what I think should be..... you can also post this on the newsgroup comp.lang.perl.tk and see what others may come up with. Maybe pack isn't the best manager for this? I don't dabble much in other geometry managers.


I'm not really a human, but I play one on earth Remember How Lucky You Are

Replies are listed 'Best First'.
Re^8: perltk autoresize following users resize
by zentara (Cardinal) on Aug 20, 2008 at 16:57 UTC
    Just so you get a clearer picture of how packing works, try this: Put your Exit button first in the packing in your buildBUI sub, and it will now be the last thing to be chopped off. Of course your frames gets squished instead.
    sub buildGui { $goMainWindow = new MainWindow; #pack your Exit button first in the list my ($oExit) = $goMainWindow->Button(-text => 'Exit', -command => sub{exit}, )->pack( -padx => '5', -pady => '5', -side => 'bottom', ); ...... ....... .....

    I'm not really a human, but I play one on earth Remember How Lucky You Are
Re^8: perltk autoresize following users resize
by rpelak (Sexton) on Aug 20, 2008 at 20:26 UTC
    Your second sentence was
    The mainwindow will automatically pack itself to the smallest size that will show everything.
    And really that is exactly what I want it to do again. Before the user messes with the window size, it seems to automatically pack itself to the smallest size that shows all when pack and unpack the frames in the labeledframe. But once the user touches it, that stops. I just want to turn that back on or have a way to do that manually.

    In my searching I just found that Tcl/TK has a function called fitToContents, but I can't find anything like that in perl/tk

    Randell
      Yeah, I see. My best guess is to save the minimum geometry needed, and set it everytime A is selected. I guess if you wanted perfect fitting everytime, you could loop thru all the widgets, get their reqwidth and reqheight, sum them up with a small fudge factor added for padding, then set your mainwindow geometry to that.

      Personally, I think the scrolled Pane is the best. Let the Scrolled Pane do all the expansion/contraction for you.


      I'm not really a human, but I play one on earth Remember How Lucky You Are
        odd question...
        you said to post to comp.lang.perl.tk newsgroup
        Is that the same as the google group?
        Assuming it isn't... how do I post to that. A google search turned up the FAQ a bazillion times, but not that actual newsgroup...

        Randell