Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw
 
PerlMonks  

Tk::ProgressBar and a long parsing process

by reneeb (Chaplain)
on Sep 28, 2005 at 18:16 UTC ( [id://495855]=perlquestion: print w/replies, xml ) Need Help??

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

Hi,

I want to show a ProgressBar while a file is parsed. I've tried this code:
#!/usr/bin/perl use strict; use warnings; use Tk; use Tk::ProgressBar; my $mw = tkinit; my $btn = $mw->Button(-text => 'start...', -command => \&readdr)->pack +(); MainLoop; sub readdr{ my $top = $mw->Toplevel(); my $progress = $top->ProgressBar( -from => 0, -to => 100, -colors => [0,'green'], -gap => 1)->pack(); $progress->update(); my $file = '/path/to/file.ext'; my $id = $progress->repeat(2,sub{ my $values = $progress->value(); $progress->value($values+2); $progress->update(); }); my $result = MyParser->new($file); $id->cancel(); }

But this doesn't work. The toplevel is shown, but the repeat-function is never executed.
What can I do?

My system:
* WinXP Home
* Tk 804.027
* ActivePerl 5.8.6

Replies are listed 'Best First'.
Re: Tk::ProgressBar and a long parsing process
by zentara (Archbishop) on Sep 28, 2005 at 20:19 UTC
    Your problem is going to force you to get down into the code, and understand how the Tk-event-loop works. Think about how a "single-threaded process" runs.....it can only be doing one thing at a time, unless you figure out a way to time slice the execution, to process sub1 for x microseconds, then sub2 for x microseconds, etc,etc. That is why in a Tk (or any gui program), if you run "sleep" or system(), the GUI stops updating while the system command does it's work.

    So what is happening in your code, is that when you hit the line "my $result= MyParser->new($file)"; the process devotes all it's time to running that, and Tk is left with no cpu time.

    So there are many ways devised to work around it. One would be to go into the MyParser package, and put a "$mw->update" in the loop that processes the file. Now in order to make it work, you may need to pass "$mw" into the package when it is created.

    Other things can be done, but you havn't showed the MyParser code. You could run the parser in a thread, a piped open, or IPC::Open3, and alot of examples for doing that abound.

    If you cannot change the MyParser package to do some $mw->update's, you could start the Progressbar, then "fork-and-exec" the code that parse the file, and when the parsing is done, cancel the repeat. Of course you will lose percentage accuracy that way, but threads would allow it. Just remember, if you use a thread with Tk, the thread must be created before you create any Tk windows. I usually create a thread, put it to sleep, and control it from Tk thru shared variables. An example is in the readmore.


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

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://495855]
Approved by pboin
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others chilling in the Monastery: (4)
As of 2024-03-29 02:06 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found