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

I have complicated TK window. The data and buttons in the window relate to a variable $product that can take one of several values. The window has many widgets: menus, labels, option buttons, entry forms, etc. All of these widgets depend on the currently selected $product.

The user can select a product to work on from a top menu in the window.

Currently, I am doing something brutish to rebuild the window when the user selects a new product to work on:

# note: $TOP is a global, the MainWindow sub create_screen { $TOP->destroy if $TOP; # brutish! $TOP = MainWindow->new( title => 'product' ); $TOP->optionAdd( "*tearOff", "false" ); ... etc ...
Destroying the whole window seems a very crude way to refresh it. It also causes a noticable blink of almost a second.

What's the polite way to redraw the screen, if some of the widgets weren't/can't be tied with $textvariable, etc?

Thanks, gang, for all the TK advice and help.

It is very much appreciated --

waterwaterwater

Replies are listed 'Best First'.
Re: TK: rebuild entire main window, more elegant soln?
by BrowserUk (Patriarch) on Oct 10, 2004 at 02:58 UTC

    The normal gui trick is to either hide or disable those controls that don;t make sense at any given time.


    Examine what is said, not who speaks.
    "Efficiency is intelligent laziness." -David Dunham
    "Think for yourself!" - Abigail
    "Memory, processor, disk in that order on the hardware side. Algorithm, algorithm, algorithm on the code side." - tachyon
Re: TK: rebuild entire main window, more elegant soln?
by pg (Canon) on Oct 10, 2004 at 03:59 UTC

    Other than what BrowserUK has said, you could also consider multiple child frames, each for one product, and just show or hide them base on the product selected.

    If most of the controls are shared among products, then BrowserUK's is better; otherwise, it makes more sense to use multiple frames.

    It also could be a mixture of those two approaches. Group those products that share most of their controls, and use one frame for them, and share or hide controls; but use a different frame for each group.

Re: TK: rebuild entire main window, more elegant soln?
by castaway (Parson) on Oct 10, 2004 at 09:19 UTC
    You may want to rethink your design. I would guess that not *everything* changes.. At least the menu from which a product can be chosen is the same, I assume? Probably other menus are too, more or less.

    If you want to keep the current design, it may be nicer (quicker refresh), if you change the labels of things, rather than redraw the entire lot. Unless the layout changes per product? Ie. When creating menus, buttons, checkboxes etc, the first time, keep a reference to the actual created object around, maybe in a nice hash hierarchy, and when a different product is selected, go through the hash and update the text/variable/label properties of the objects.

    If you can change the design, I'd suggest a top window that stays the same, even if it does just contain a menubar, and sub windows, or DialogBoxes (new top windows) for each product selected. That way also, your users can compare product data, should they ever want to ,) (And these subwindows you can destroy and redraw.. or just draw another one when another product is selected, and give each an explicit close button)

    C.

Re: TK: rebuild entire main window, more elegant soln?
by zentara (Cardinal) on Oct 10, 2004 at 13:41 UTC
    Like others have said, "rethink your design". One thing to consider when you start destroying windows, is "memory-leaks" caused by stray objects left laying around.

    The best strategy is to try to design your app, to create widgets once, then reuse them, by reconfiguring them as needed. If your layout fluctuates wildly from one selection to another, you might consider a menu at the top, with a frame underneath. You could have a graphic as the default view in the frame, and when a new selection is made, the graphic is shown, while the new window is built, and display it once done. You can build windows and frames while they are in a hidden state. They are not shown, until you "pack" them. Also there is "packForget" for removing something. So, for instance, in your display frame, when a new selection is made, you could "$frame->packForget", then reconfigure the frame, then pack it again. It can get tricky, but it can be done. Just remember to watch your memory usage as you test it. Nothing is more frustrating than getting something to run "like you want", only to find out later, that it jumps in memory 10 megs with every button click. :-( .....neccesitating a redesign.


    I'm not really a human, but I play one on earth. flash japh