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

In building my application under Perl/Tk, I need to build up some menus from servers and database accesses. This all functions well, but there is an interval between starting the gui, and the screen being populated with widgets (main window, menus, etc). While this is happening the present solution is to do "print"s which go to standard out that explain the happenings. After all the menus and stuff are built, I call "MainLoop" and I have a gui. What I'd like to do is have a nice scrolling status window that reflects the writings to stdout (I'll change the print(s) as needed) to a nice window that is seperately displayed. Is there any way I can display a window (or anything for that matter) OUTSIDE of the 'MainLoop' procedure? The references are a bit vague on this. I suspect I'll need something like a TopLevel widgit or something, but I'm a bit unsure.

p.s. I got the browser select goodie working! Thanks.

Replies are listed 'Best First'.
Re: Perl/Tk windows and status
by strat (Canon) on Jan 17, 2006 at 08:53 UTC

    If your startup takes too long, you could either use a nice splash or just build the most important widgets before MainWindows and build the rest with one (or several) Tk::after...

    Best regards,
    perl -e "s>>*F>e=>y)\*martinF)stronat)=>print,print v8.8.8.32.11.32"

Re: Perl/Tk windows and status
by zentara (Cardinal) on Jan 17, 2006 at 12:43 UTC
    There are a couple of different ways. 1 way would be to start your Mainloop with a timer that starts after1 millisecond, to start your long startup process.
    $mw->after(1, sub {&startup()}); MainLoop;
    That will allow the MainLoop and window to get up and running, before you start your long startup process.

    Alternatively you can use waitvisibility, which tells the MainLoop to get the window up before proceeding past that point in the code.

    So here is an example, using a simple sleep. However, this is where your REAL problem lies, how to get the STDOUT from your startup processes into your textbox. I've shown 2 subs. One is the standard insert with update, but that won't do you any good if some other program is writing to STDOUT. (Unless you use piped opens, IPC::Open3, etc)

    But there is a trick for tieing STDOUT to the test widget, which I have shown. Now, you still need to update the text widget, which I have done in the simple loop. But in your real application startup, you will probably need to resort to a timer which updates the text widget on an interval.

    #!/usr/bin/perl use warnings; use strict; use Tk; my $mw = tkinit; my $textbox = &do_Toplevel(); #to wait until a $widget is visible, use waitVisibility: $mw->waitVisibility; #your long startup code, telling it which textbox to display in #&startup($textbox); &startup1($textbox); MainLoop; ################################################################# sub do_Toplevel { my $tl = $mw->Toplevel(); $tl->title( "Early Status" ); my $text = $tl->Scrolled('Text')->pack(); $text->insert('end',"........startup messages.........\n"); $tl->Button( -text => "Close", -command => sub { $tl->withdraw } )->pack; return $text; } ############################################################## sub startup{ my $textbox = shift; foreach my $num (1..10){ $textbox->insert('end',"$num\n"); $textbox->update; sleep 1; } } ################################################################## sub startup1{ my $textbox = shift; $|++; tie *STDOUT, 'Tk::Text', $textbox; #may need this to force repeated updates # $mw->repeat(10,sub{ $textbox->update }); foreach my $num (1..10){ print "$num\n"; # printing to STDOUT $textbox->update; sleep 1; } } __END__

    I'm not really a human, but I play one on earth. flash japh
Re: Perl/Tk windows and status
by PodMaster (Abbot) on Jan 17, 2006 at 06:53 UTC
    Use update, and your widget will display

    MJD says "you can't just make shit up and expect the computer to know what you mean, retardo!"
    I run a Win32 PPM repository for perl 5.6.x and 5.8.x -- I take requests (README).
    ** The third rule of perl club is a statement of fact: pod is sexy.

Re: Perl/Tk windows and status
by blazar (Canon) on Jan 17, 2006 at 08:22 UTC

    It is my understanding that you can't do that until MainLoop anyway. So a solution could be to fork off an helping application, establish some form of IPC between it and your program and have it do the splash screen/scrolling status thing until the latter is finished.

    Alternatively you may build a first, "presentation" GUI that does the scrolling status thing while collecting data from db access, then rebuild it with that data and update.

    Whatever, be patient and I bet zentara will come up with a Nx (N a reasonably sized integer!) better solution and most probably actual example code!

Re: Perl/Tk windows and status
by Ultra (Hermit) on Jan 17, 2006 at 07:10 UTC

    I don't think there's a way to have a log window running, without having MainLoop started (which handles all windows activities).

    Dodge This!