http://www.perlmonks.org?node_id=372816


in reply to Keeping the user informed: A Tk/Threads question

"Once the user clicks OK the file is processed and added to the block of data from which the reports will be produced. This data may take 10 to 15 minutes .. at most 30 minutes to import. What can I do to keep the user informed that the process is indeed still "working as intended" and not DoA"

Here are a couple of ideas.

If the file you open for processing has a fully readable filehandle, you can count the lines in the filehandle, to use as a max in the Tk::Progressbar, then rewind the filehandle to process it. Increment the progressbar 1 for each line processed. Here is an example that will make a progressbar for a couple of files.

sub do_while { use Fcntl qw(:seek); #count lines and rewind while(<FILE0>){$linetotal++} seek FILE0, 0, SEEK_SET or die "Cannot rewind file: $!"; while(<FILE1>){$linetotal++} seek FILE1, 0, SEEK_SET or die "Cannot rewind file: $!"; while(<FILE2>){$linetotal++} seek FILE2, 0, SEEK_SET or die "Cannot rewind file: $!"; print "$linetotal\n"; $progressbar = $main->ProgressBar( -length => 200, # Actually width -width => 20, # Actually height -gap => 0, -value => 0, -colors => [0, 'pink'], )->pack(-pady => 5, -padx => 5); while (<FILE0>) { my $line = $_; chomp($line); do_opt0($line); if ( $line ne $token ) { print SFILE "$token"; } $progressbar->value($progressbar->value + (100/$linetotal) ); $main->update; } while (<FILE1>) { my $line = $_; chomp($line); do_opt1($line); if ( $line ne $token ) { print SFILE "$token"; } $progressbar->value($progressbar->value + (100/$linetotal) ); $main->update; } while (<FILE2>) { my $line = $_; chomp($line); do_opt2($line); if ( $line ne $token ) { print SFILE "$token"; } $progressbar->value($progressbar->value + (100/$linetotal) ); $main->update; } }

If you don't know the size of the files, like if its coming in off of a network, you could use the Tk::ExecuteCommand module, which opens up a nice box, has a blinking cancel button, and shows STDOUT and STDERR. Here is a simple example:

#!/usr/bin/perl use warnings; use strict; use Tk; use Tk::ExecuteCommand; my %commands = ( #buttontext => command sleep => 'sleep 20', dir => 'dir', ls => 'ls -la', ); my $mw = MainWindow->new; foreach my $key (keys %commands){ $mw->Button(-text => $key, -command=>[\&execute, $commands{$key}] )->pack; } $mw->Button(-text => 'Quit', -command=> sub{Tk::exit} )->pack; MainLoop; sub execute { my $command = shift; my $tl = $mw->Toplevel( ); $tl->title($command); $tl->Button(-text => "Close", -command => sub { $tl->withdraw })->pack; my $ec = $tl->ExecuteCommand( -command => $command, -entryWidth => 50, -height => 10, -label => '', -text => 'Execute', )->pack; $ec->bell; $ec->update; }

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