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

I looked at the adjuster and it didn't do what I needed... so let me try to explain better.

I have a window, I put in a labeledframe which we can call foo. In it, I put a checkbox (enable foo) and a frame(which I use as a kind of container). If you uncheck the checkbox, the container frame is packForget'ed. If you recheck it, it is pack'ed. By default, the whole window resizes after each change. But if while it is unchecked, the user resizes the window slightly (in the y direction), then if they check the checkbox it will not resize to fit the new contents, causing them to be off the bottom of the gui.

So when the user does a manual resize, it does something to stop the automatic resizing. I want to turn the auto resizing back on.

Of course I could manually handle the resizing in this case, but in the real case there are just too many widgets and too many other things to make that effective.

Randell
  • Comment on Re^4: perltk autoresize following users resize

Replies are listed 'Best First'.
Re^5: perltk autoresize following users resize
by zentara (Cardinal) on Aug 19, 2008 at 19:10 UTC
    As usual, there probably is a solution, but without a small code example that demonstrates it, I'm not going to take the time to write it from scratch. You give a good explanation of what you want, but it all boils down to how you are actually coding it. It sounds to me, like you want to use that previous example I showed, that gets the new window measurements after a resize, and do some sort of repacking/packPropagation trickery. If you did make a minimal example, you could also post it on comp.lang.perl.tk, and get more eyes looking at it. If worse comes to worse, you could completely withdraw the top window, repack everything, then raise it. But you get a crummy flicker that way. Also, there may be other techniques than what you are using, which is unknown to us. Maybe all you need to do is do a geometry statement with the new size, then update/packPropagate the window.

    I've found when you get into these esoteric situations, there is usually a way out by putting things into a scrolled Pane or something similar. like deep nesting of frames with expand set.


    I'm not really a human, but I play one on earth Remember How Lucky You Are
      fair enough...
      Below is some example code.
      If you run that, you can check and uncheck the checkboxes and the window will resize to fit the contents.

      But if you uncheck the enable A checkbox, then manually resize the window a tiny bit in the +Y direction. Then recheck the enable A checkbox, the auto resize will stop and it will push the exit button off the visible window.

      I don't know what handles that automatic resizing. So I don't even know where to look. But somehow it gets turned off, and I would like to turn it back on.
      I would expect if I could turn it back on that it would add space or remove space equal to the size of the widget getting packed or unpacked, since that is what it seems to do before a manual user resize.

      I could of course take over the resizing operation in my code, for everything that gets packed and unpacked, but in the real case, that would be a ton of stuff, and not practical. Which is why I am looking to turn the auto resizer back on. It is really kind of a crop or fit function...
      #!/usr/bin/perl use strict; use Tk; our ($goMainWindow); our (%ghGuiObjs); our (%ghGuiCBVars); $| = 1; &main(); sub main { buildGui(); MainLoop; } #end sub main sub updateA { if ( $ghGuiCBVars{"nEnableFrameA"} == 1 ) { $ghGuiObjs{"oContainerA"}->pack(); } else { $ghGuiObjs{"oContainerA"}->packForget(); } } sub updateB { if ( $ghGuiCBVars{"nEnableFrameB"} == 1 ) { $ghGuiObjs{"oContainerB"}->pack(); } else { $ghGuiObjs{"oContainerB"}->packForget(); } } sub buildGui { $goMainWindow = new MainWindow; my ($oLabel) = $goMainWindow->Label( -text => "This is my example", )->pack( -padx => '5', -pady => '5', -expand => '1', -fill => 'x', ); my ($oCbA) = $goMainWindow->Checkbutton( -text => 'Enable A', -variable => \$ghGuiCBVars{"nEnableFrameA"}, -command => \&updateA, -anchor => 'w', ); $ghGuiCBVars{"nEnableFrameA"} = 1; my ($oFrameA) = $goMainWindow->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) = $goMainWindow->Checkbutton( -text => 'Enable B', -variable => \$ghGuiCBVars{"nEnableFrameB"}, -command => \&updateB, -anchor => 'w', ); $ghGuiCBVars{"nEnableFrameB"} = 1; my ($oFrameB) = $goMainWindow->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', ); }
        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.

        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