I have a small Perl Tk app with a text window that I want to be updated in a non buffered way like I have with my log files but I can't get it to work due to my poor understanding of everything to do with Perl.
The app reads an xml index, parses it then loads each id found in the xml as a url to cache the page. These can number from 1700 to 19,000 depending on which $pubId is entered and takes a couple of hours.
I have the following code for the Submit button and the text window:
my $submit_image = $pict->Photo(-file => $submit);
my $submit_button = $mw->Button(
-image => $submit_image,
-text => "Submit",
-background => "#cccccc",
-command => sub {
if ($pubId eq '') {
$|;
Log_message ("\n$DATE - $TIME - WARNING: Please complete all fields\t");
tk_message ("Please enter a valid Publication ID");
}
else {
request_url(); #Open the xml url and read it in
}
$text->insert(
# put something to the _end_ of the text
# which is in the widget
'end',
sprintf(" $txtmesg\n")
);
# Set window to the end of the text
# I want to see the newest events immediately
$text->see('end');
}) ->place( -x => 60, -y =>195);
which works if the button is pressed with an empty or invalid $pubId (request_url does a further check to see if the html body contains the word 404 and erro开发者_JAVA百科rs out a message to the window).
But if everything is ok and request_url() runs, then the whole Tk window freezes and I can't use my exit button and have to close it via the command prompt.
I know I should be doing this differently but so far every site I have looked at is too complicated for me and I just get baffled. I'm looking for some noddy instructions to enable me to work through this.
Thanks.
EDIT: I have now tried to use MainLoop(); and the DoOneEvent(): within my sub but I am still seeing the same gui freeze and no window updates.
I will continue to research and experiment.
-command => \&long_job)
MainLoop();
sub long_job {
if ($pubId eq '') {
$|;
Log_message ("\n$DATE - $TIME - WARNING: Please complete all fields\t");
tk_message ("Please enter a valid Publication ID");
}
else {
DoOneEvent();
request_url(); #Open the xml url and read it in
}
}
Not sure if this will help others with a similar problem, but just in case it does:
MainLoop();
is what "starts" the tk process. Good practice would be to set up all your widgets, callbacks and anything you want to show up on screen first, then call the MainLoop()
. Processing should occur after the MainLoop()
is called. In the above, you will probably need to call
$myLabel->update;
inside the loop on whatever it is you are using to display your output. In my case I was using a Label
to output progress messages in a loop that made calls using system()
. Using ->update
solved it perfectly (while DoOneEvent()
did not).
Hope that helps somebody out there.
精彩评论