in reply to Perl Tk Asynchronous Progress Updates

G'day hermes1908,

Welcome to the monastery.

I don't think your users would be too happy having to manually update the download progress by pressing a button. This is really something you'd want to display dynamically. Consider how it's done in a simple text-based scenario (e.g. wget) or in a graphical context such as your browser: you don't need to hit keys or press buttons to see what progress has been made.

When designing a GUI, think about how it's been done previously and how your users would expect it to work. Unless you are intending to present something that is fundamentally different from the norm, stick with the status quo.

Here's a working (albeit barebones) script that simulates 3 files being downloaded simultaneously and shows progress dynamically.

#!/usr/bin/env perl use strict; use warnings; use Tk; use Tk::ProgressBar; my @file_data = ( { name => 'File1', size => 1000 }, { name => 'File2', size => 5000 }, { name => 'File3', size => 2500 }, ); my $mw = MainWindow->new(); $mw->geometry('400x200+50+50'); my $control_F = $mw->Frame()->pack(-side => 'bottom'); $control_F->Button(-text => 'Exit', -command => sub { exit } )->pack(-padx => 5, -pady => 5); my $progress_F = $mw->Frame( )->pack(-padx => 10, -pady => 10, -fill => 'both', -expand => 1); for my $file_datum (@file_data) { my $download_amount = 0; my $download_percent; my $download_F = $progress_F->Frame( )->pack(-padx => 10, -pady => 10, -side => 'top', -fill => 'x' +); $download_F->Label(-text => $file_datum->{name} )->pack(-padx => 5, -side => 'left'); $download_F->ProgressBar(-variable => \$download_percent )->pack(-padx => 5, -side => 'left', -fill => 'x', -expand => +1); $download_F->repeat(25 => sub { $download_amount += int rand 10; if ($download_amount > $file_datum->{size}) { $download_amount = $file_datum->{size}; } $download_percent = $download_amount / $file_datum->{size} * 1 +00; }); } MainLoop;

-- Ken

Replies are listed 'Best First'.
Re^2: Perl Tk Asynchronous Progress Updates
by Anonymous Monk on Jul 02, 2013 at 15:32 UTC
    Thanks for the example, but the idea was that I would prompt the user for input (using an entry widget) and then initiate the download. The updates are supposed to be asynchronous so a button doesn't need to pushed to see the progress. The idea is that once a download has been initiated the update function should run in the background so as not to hang up the application (the download link is retrieved via an entry widget). Your sample code has the same issue that mine did, namely that the download routine runs before the gui is even displayed. Do you have the same issue when you run your code? Perhaps something is wrong with my version of Tk ( though I've had this problem on two different machines running different linux distributions, so that's unlikely).
      I think that you may be missing the focus of kcott's post. It is the repeat function.

      Obviously, you start the progress bar when you are ready.

      Example

      use Tk; use Tk::ProgressBar; my $mw = MainWindow->new(); my $per = 0; $mw->ProgressBar(-variable=>\$per)->pack; $mw->Button(-text=>"Go",-command=>\&GoForIt)->pack; MainLoop; ######### This is the important bit ########### sub GoForIt { $mw->repeat(25=>sub{$per+=10;return if $per>100;;$mw->update;sleep +(1)}) }

      What you're describing doesn't make any sense to me: I can't see how the (simulated) downloads in my code could have possibly run before the GUI is displayed.

      When you ran my code, did you really see all progress bars showing completion? I see them starting at the far left and moving towards the right.

      Did you change my code before running it? I can't think of any reason why the code I posted would not run, as is, under Linux; however, if you did change it, please show the actual code you are running.

      -- Ken

        I ran the code unmodified (Well, I added a "MainLoop" to the end since it was missing). The application paused before starting then displayed the progress bars full. I think it may be an issue with my Tk package, I am going to try it on another machine.

        Thanks
        Hermes.