The problem I'm having is that calling this update() seems to defeat the $main->Busy() I'm using to prevent the user from being able to take any actions while the calculation is running, so that the user may inadvertently interrupt the calculation before it's finished.
Is there a way to update my status label without allowing any events that may come in during the update to sneak around the grab that the Busy is supposed to be doing? Or am I just confused?
The Tk faq mentions configuring the cursor. Very possibly your system has a "busy, but what do you want?" cursor like an hourglass *and* a pointer. Perhaps you could use that?
My own experience with GUIs was with GTK, so I haven't actually tried this. YMMV.
Any thoughts on the merits of idletasks() vs update() ?
(I always set that, except in exceptional circumstances, and so ass-u-me-d that $child->update would not affect $otherchild.)
Does anyone know what the behavior of setting (un)Busy an already (un)Busy widget is "supposed" to be?
I think this might be my problem.
Contrary to the assertion that any update is global, the 2nd run of my test script shows that with Busy(-recurse=>1) and $label->update, the $button event was discarded. (On the Win98 and W2K boxen here, anyway.)
Update: I'd changed two things at once while testing - the recurse option was solely responsible for causing the events to be discarded. Update is global.
Also, idletasks is slightly different between the Win* and Linux boxen I use. On the Linux boxen there are no "leftover" characters after idletasks causes the label change to display.
#!perl
use strict;
use warnings;
use Tk;
my $top = MainWindow->new();
my $txt = $top->Text->pack;
for my $t ('a' .. 'z') {
$txt->insert('end', $t x 40 . "\n");
}
my $lbltxt = "wowowowowowowowowowowowowowo";
my $label = $top->Label(-textvariable => \$lbltxt)->pack;
my $button = $top->Button(-text => "Die", -command => sub { exit; })->pack;
$top->update;
#$top->Busy(-recurse => 1); # use
$top->Busy; # drop
sleep 8;
$lbltxt = "updatedupdated";
#$label->update; # use
$label->idletasks; # drop
sleep 8;
$txt->delete('1.0','end');
$top->Unbusy;
Tk::MainLoop;
Run this, click on the "Die" button as soon as the window appears. After the first sleep, the label is changed, but since the new text is of shorter length several "wowo" characters remain on either side of "updated". After the 2nd sleep and the Unbusy, the "Die" event occurs and the program exits.Comment out the "drop" lines and uncomment the "use" lines.
Run now, click "Die" before the label changes. This time there are no leftover characters, and the "Die" event is discarded. After the Unbusy the program continues.
... $mw->Unbusy(); $mw->update(); $mw->Busy(); ...
I think a combination of using idletasks()and making sure not to (Un)Busy an already (Un)Busy widget (by keeping a global indicator of the Busy state of the widget) seems to be working the way I had envisioned (although I'm still testing).
Thanks all.
But, unfortunately, this is Unix-only.
perlmonks.org content © perlmonks.org and Anonymous Monk, Crian, eserte, gaal, keszler
prlmnks.org © 2006 edmund von der burg (eccles & toad)
v 0.03