Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chriss Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Perl/Tk - display "%completed" at the bottom

Status
Not open for further replies.

MoshiachNow

IS-IT--Management
Joined
Feb 6, 2002
Messages
1,851
Location
IL
Hi,

How would I display "%completed" at the very bottom (grey)of my main window during the progress of the main loop ?

Thanks

Long live king Moshiach !
 
Check out Tk::StatusBar:


It adds a status bar widget to the bottom of your window, which I think is what you're looking for.

You can then put in a progress bar and a % completed widget too.

Code:
my $sb = $mw->StatusBar;

$sb->addProgressBar (
   -length  => 60,
   -anchor  => 'left',
   -from    => 0,
   -to      => 100, # 0 - 100%
   -variable => \$progress,
);

my $textProg = $sb->addLabel (
   -width   => 20,
   -anchor  => 'left',
   -text    => '0% completed', # we'll update this widget later
);

# your main loop to update $progress
while (1) {
   select (undef,undef,undef,0.01);
   $mw->update;

   # update $progress
   if ($progress < 100) { # less than 100%
      $progress += 5; # 5% at a time...
      # and the progress bar updates instantly

      # update the text widget too
      $textProg->configure (-text => "$progress\% completed");
   }
}

There's not much you can do about the text widget because it contains both a variable AND text that isn't involved in the variable. If you want, you can do -textvariable on the label and then just do

$text = "$progress\% completed";

and the label widget will update with that too.

Note:

Tk::StatusBar isn't a standard Tk widget, but it's not hard to install either. A quick and simple way: on the CPAN page, right-click "View Source" and do "Save Target As", and save it to C:\perl\site\lib\Tk\StatusBar.pm (assuming that's the path to your Perl lib where Tk's modules are)
 
Ah, thanks for catching that one. ;)

The select command is the only way I know of to have a sleep of a non-integer value. The sleep() command takes integers only, so that sleep(.5) rounds off to sleep(0) which doesn't sleep at all (it would be the same as int(.5) = 0)

From perlfunc:
select RBITS,WBITS,EBITS,TIMEOUT

This calls the select(2) system call with the bit masks specified, which can be constructed using fileno and vec, along these lines:

$rin = $win = $ein = '';
vec($rin,fileno(STDIN),1) = 1;
vec($win,fileno(STDOUT),1) = 1;
$ein = $rin | $win;

If you want to select on many filehandles you might wish to write a subroutine:

sub fhbits {
my(@fhlist) = split(' ',$_[0]);
my($bits);
for (@fhlist) {
vec($bits,fileno($_),1) = 1;
}
$bits;
}
$rin = fhbits('STDIN TTY SOCK');

The usual idiom is:

($nfound,$timeleft) =
select($rout=$rin, $wout=$win, $eout=$ein, $timeout);

or to block until something becomes ready just do this

$nfound = select($rout=$rin, $wout=$win, $eout=$ein, undef);

Most systems do not bother to return anything useful in $timeleft, so calling select() in scalar context just returns $nfound.

Any of the bit masks can also be undef. The timeout, if specified, is in seconds, which may be fractional. Note: not all implementations are capable of returning the $timeleft. If not, they always return $timeleft equal to the supplied $timeout.

You can effect a sleep of 250 milliseconds this way:

select(undef, undef, undef, 0.25);

Note that whether select gets restarted after signals (say, SIGALRM) is implementation-dependent. See also perlport for notes on the portability of select.

On error, select behaves like the select(2) system call : it returns -1 and sets $!.

Note: on some Unixes, the select(2) system call may report a socket file descriptor as "ready for reading", when actually no data is available, thus a subsequent read blocks. It can be avoided using always the O_NONBLOCK flag on the socket. See select(2) and fcntl(2) for further details.

WARNING: One should not attempt to mix buffered I/O (like read or <FH>) with select, except as permitted by POSIX, and even then only on POSIX systems. You have to use sysread instead.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top