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

Hi there dear monks,

I've seem to have stumbled on a problem I can't get solved. My script is a basic "input-convert-to-output" script and it works fine. The problem is the GUI i wrote that makes handling the script a little easier. The GUI itself works fine (again), but the troubles begin when i move the script to another computer that has a different screen-resolution. It doesn't matter whether or not the OS of the computer is the same (linux, mac or windows), the only thing that seems to influence (and alter) the GUI appearance is the resolution.

For some reason, the GUI MainWindow becomes either smaller or larger, while the widgets inside the MainWindow remain 'normal', causing the GUI to look terrible (seeing buttons and frames vanish cause of a very small mainwindow is not very good). I've searched the internet for hours, read perl books,... but I can't seem to find any information about how to 'solidify' (in a lack of better terms) the width and height of the mainwindow (so not the widgets inside it). Apparently I can't use centimeters, inches or any other form of solid distance measurements for the geometry() function at the mainwindow. I tried but failed miserably :)

Therefore, the obvious question is: can someone help me here and try to fix this.

#only a small relevant portion is shown here my $mw = MainWindow->new; my $width = '350'; my $height = '180'; $mw->geometry( $width."x".$height); $mw->resizable(0,0); $mw->title("Calculator");

Replies are listed 'Best First'.
Re: Perl Tk geometry problem
by biohisham (Priest) on Aug 30, 2009 at 00:22 UTC
    I don't really know much about the geometry thing, but have you tried to set a proportion using the pack method options? as in:

    $child = $Mother->Button()->pack(-expand=1, -fill='both');
    Try this link, it has many things on the Geometry Manager, that I've just started reading about: Here, I really really hope it be of value to you and solve this situation. Best of Luck :).

    Update:In the pack method, widgets are given allocation rectangles, specific areas where the widgets can hang around upon resizing, this is achieved automatically for pack, the grid command, on the other hand doesn't have such a rectangle to fill-since it deals with grids- so part of your problem can be that, you have to interfere manually to put each widget in your application in Place every other time you changed to a different screen resolution. This arises because:

    1. you have explicitly used the geometry method.
    2. You haven't told the grid how to resize by giving the proper argument to the option -sticky=>.

    This way you have disabled automatic resizing completely, now, try without setting the size yourself, or use the -sticky=> option with grid or the equivalent -fill=> and -expand=> options with pack, that means, use pack instead of grid.

    be patient and it shall come your way.


    Excellence is an Endeavor of Persistence. Chance Favors a Prepared Mind.

      Well.. I use 'grid' as a geometry manager, but how can that help me determine the size and height of the Mainwindow? I use 'grid' to assign widgets (like frames and buttons) inside the mainwindow, Could you provice a code example explaining how to use 'grid' to influence the height and width of the MainWindow ?

      update: i still can't figure out how using pack to organise the widgets inside the mainwindow, would help me restrict the resizing of the mainwindow itsel? The resizing still happens when I replace the 'grid' manager with 'pack'. Do i leave the 'geometry(***x***) out?

        Whenever you use the geometry method explicitly, you are actually disabling automatic resizing which means that chances are there your GUI would not look like what you intended it to be across various platforms, I haven't tried this myself but this is what I know about it. Unless you have strong reason to declare the size yourself using geometry I would rather say let the automatic sizing take place through fidgeting with the sizes of the internal widgets and not the mother widget. Tell me how it is coming along with you . :)


        Excellence is an Endeavor of Persistence. Chance Favors a Prepared Mind.
Re: Perl Tk geometry problem
by Marshall (Canon) on Aug 30, 2009 at 22:48 UTC
    Your problem is not within this code at all. It is most likely with how you are placing the widgets within this window. Note: in your code, width and height are the minimum main window size. It will get bigger if needed (even without resizeable). Resizeable means that the user can manually re-size the window.

    The key thing is that you need to learn about Frames! A frame is a "non-visible" rectangle that is used to control screen placement with the pack geometry manager. You should always put widgets inside of frames. Pack is the most common manager and normally should be used instead of grid.

    run the below code and play... What this does is start the main window at a ridiculously small width value of "50". Then a frame is drawn inside of it. Then some buttons are "packed" in that frame. The "packing" says that all of these buttons are essentially on "one line" - ie consecutive things starting at left border of frame. This causes the width of the main window to increase so that all buttons are visible! If the buttons were just inside the main window, without the directions from the frame and pack, then they would "squish" around and do goofy things as window is re-sized. I presume this is what is happening to you.

    Turn on resizeable, ie. take # comment out below to play with manual resizing of the window to see what happens. You can't make the buttons "disappear" from the screen, even by resizing the window manually. There are ways to do that with "scrollable", but that isn't what you want!

    The windows should re-size as needed between different screen resolutions although sometimes there are some "tricks" about that. Sometimes the mapping between screen unit and font size isn't quite perfect. On my machine the name "Windows" gets squished a bit when letting Tk "grow" the mainwindow. You can just put a Label as last button in frame with say a space or two as name to force a slightly wider Window. Although you are probably going to have some other frame wider than this "button frame" that will have the same effect.
    Update: there are various "pad" things that can cause essentially similar effects for you. But without knowing more, I didn't want to get too complex im my example.

    #!/usr/bin/perl -w use strict; use Tk; #only a small relevant portion is shown here my $mw = MainWindow->new; my $width = '50'; my $height = '180'; $mw->geometry( $width."x".$height); #$mw->resizable(1,1); $mw->title("Calculator"); my $menu_f = $mw->Frame()->pack(-side=>'top',-fill=>'x'); my $menu_file = $menu_f->Menubutton (-text=>'File',-tearoff=>'false') ->pack(-side=>'left'); my $menu_tools = $menu_f->Menubutton (-text=>'Tools',-tearoff=>'false') ->pack(-side=>'left'); my $menu_windows = $menu_f->Menubutton (-text=>'Windows',-tearoff=>'false') ->pack(-side=>'left'); MainLoop();