Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight

Tk and realtime logging.

by injunjoel (Priest)
on Jun 30, 2005 at 19:39 UTC ( #471444=perlquestion: print w/replies, xml ) Need Help??

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

Greetings all,
I have been working with Tk recently and I love how easy it makes GUI development. However I have run into a bit of a problem and Im hoping it is something fairly simple to remedy.
Here is a brief desciption:
I have an object I created that handles the parsing of a particular type of text file from a shared directory on our network. I have wrapped this object in a Tk interface and everything is working just fine. However since I want to allow users to batch process directories of files I have to show them the current progress of what is going on so they don't think the computer is frozen.
  • So in Tk the user selects a directory to upload files from.
  • The script reads how many files are in the directory that match the given extention and displays "XXX files found", then produces a button "Load Files".
  • The "Load Files" button calls a subroutine "&loadfiles" and passes it an array reference of matching files from the selected directory.
The problem is within "&loadfiles" I am attempting to produce a log window
$logwin = $framename->Scrolled('Text', -height=>10, -width=>50, -scrol +lbars=>'e')->pack(-side=>'top', -padx=>4, -expand=>1);

that I can then insert file processing status to. However, when I click on "Load Files" the script is waiting for "&loadfiles" to finish before it returns anything and thus the log window only shows up after everything has been processed.
I would like to be able to create the log window first and insert parsing status as it goes through the array, otherwise the users might think the computer is frozen and start clicking like mad.

What have I tried?
I have tried creating the screen in a seperate sub, then from within the button command checking if the screen was created successfully. If so start loading the files. Still no dice.
Does this sort of thing require forking a child process that I get status from?
Any suggestions? I can post code if needed.
Thanks in advance.

Well I got it working. A combination of $Widget->update; and $framename->see("end"); did it.
Im still open to suggestions though if anyone sees a problem with my current solution. Thanks again.

"I do not feel obliged to believe that the same God who endowed us with sense, reason and intellect has intended us to forego their use." -Galileo

Replies are listed 'Best First'.
Re: Tk and realtime logging.
by Ultra (Hermit) on Jul 01, 2005 at 07:52 UTC

    Im still open to suggestions though if anyone sees a problem with my current solution. Thanks again.

    I don't see any problem with your approach. A similar one can be found on this thread: Perl/Tk App and Interprocess Communication

    Another approach would be using POE, an "event driven" framework to sum it up shortly. This would be a simple example.

    Dodge This!
Re: Tk and realtime logging.
by zentara (Archbishop) on Jul 01, 2005 at 12:32 UTC
    A combination of $Widget->update; and $framename->see("end"); did it. Im still open to suggestions though if anyone sees a problem with my current solution.

    Just for the sake of discussion........

    The problem which you present and the solution which you chose, have been talked about numerous times in different Tk threads...usually named something like "updating my Tk window".

    Without seeing your code, but from your description, it sounds like the solution you have selected, is "not finely grained in realtime". It sounds like you upload a file, and when it's done, report it is done with a count of total_done and total_max. Thats usually good enough, but what if the files are very big, and take many minutes between updates?

    In those cases you need to find an "upload subroutine" which triggers a callback for every 10k transfered. Now wget, curl, and lwp all have methods for downloading with this callback. If you search around through the snippets section, you should find examples with Tk.

    Here is the basic lwp code for doing it. I'm just showing the lwp code, but you could see how to it could be incorporated into your Tk code to show a progessbar. Like I said, it makes a difference when your files are big, and bandwidth is low.

    Check out tk-http-file-upload-w-progress

    #!/usr/bin/perl -w #from lwpcook use LWP::UserAgent; $ua = LWP::UserAgent->new; $URL = ''; $filename = substr( $URL, rindex( $URL, "/" ) + 1 ); #print "$filename\n"; open( IN, ">$filename" ) or die $!; my $expected_length; my $bytes_received = 0; my $res = $ua->request(HTTP::Request->new(GET => $URL), sub { my ( $chunk, $res ) = @_; $bytes_received += length($chunk); unless ( defined $expected_length ) { $expected_length = $res->content_length || 0; } if ($expected_length) { printf STDERR "%d%% - ", 100 * $bytes_received / $expected +_length; } print STDERR "$bytes_received bytes received\n"; # XXX Should really do something with the chunk itself print IN $chunk; } ); print $res->status_line, "\n"; close IN; exit;

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

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://471444]
Approved by bofh_of_oz
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others romping around the Monastery: (5)
As of 2019-07-21 18:54 GMT
Find Nodes?
    Voting Booth?
    If you were the first to set foot on the Moon, what would be your epigram?

    Results (9 votes). Check out past polls.