in reply to Keeping the user informed: A Tk/Threads question
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; }
|
|---|