For Programmers: Free Programming Magazines  


Home > Archive > PerlTk > October 2005 > Pausing Perl/Tk UI









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author Pausing Perl/Tk UI
Daniel Qarras

2005-10-08, 6:57 pm

Hi all,

I've created a Perl/Tk program that demonstrates
operation of a system. It draws arrows from box to box
to present the event flow. While drawing arrows
there's a pause between arrows achieved by calling
function pause_flow() and in my code I call it in
needed places. It looks like this:

sub pause_flow() {
$mw->update();
sleep(1);
}

I found out that UI is unresponsive during that
sleep(1). I have a pause button in the UI
that would pause the whole execution but it doesn't
work during that sleep(1). This must be rather easy to
fix but I haven't yet find the right solution. I tried
$mw->after(1000) but it also caused UI to be
unresponsive for that one second (I guess it means
that while executing pause_flow() no other methods may
be called?). So is there a way to allow user to
pause/halt UI even while program is executing sleep()
or after()?

The pause button is at the moment implemented like
this:

sub pause_button_command {
if ($continued == 0) {
$pause_button->configure(-text => "Pause");
$continued = 1;
}
else {
$continued = 0;
$pause_button->configure(-text => "Continue");
$mw->waitVariable($continued);
}
}

Thanks.
Eric Bohlman

2005-10-08, 6:57 pm

Daniel Qarras <dqarras@yahoo.com> wrote in news:di8k6q$hqn$1
@nyytiset.pp.htv.fi:

> Hi all,
>
> I've created a Perl/Tk program that demonstrates
> operation of a system. It draws arrows from box to box
> to present the event flow. While drawing arrows
> there's a pause between arrows achieved by calling
> function pause_flow() and in my code I call it in
> needed places. It looks like this:
>
> sub pause_flow() {
> $mw->update();
> sleep(1);
> }


Look into the after() and repeat() methods.
zentara

2005-10-09, 6:57 pm

On Sat, 08 Oct 2005 17:14:13 +0300, Daniel Qarras <dqarras@yahoo.com>
wrote:

>I've created a Perl/Tk program that demonstrates
>operation of a system. It draws arrows from box to box
>to present the event flow. While drawing arrows
>there's a pause between arrows achieved by calling
>function pause_flow() and in my code I call it in
>needed places. It looks like this:
>
>sub pause_flow() {
> $mw->update();
> sleep(1);
>}
>
>I found out that UI is unresponsive during that
>sleep(1). I have a pause button in the UI
>that would pause the whole execution but it doesn't
>work during that sleep(1).


In GUI programs, it's almost always a bad design if you need
to use a while(1) loop or a sleep() statement. This is because
it interferes with the Tk event loop, and makes the UI unresponsive.

What you need to do is rethink the design of the loop which
controls the drawing of the arrows. The easiest way is to use a flag
variable.

Something like this (timers need adjustment to suit your needs).

my $continue_flag = 1;

#run the arrows
$mw->repeat(100, sub {

if ( $continue_flag ){
my $arrow_num = shift @arrows
&do_next_arrow( $arrow_num );
}else{ next }

});

#10 second pause
$mw->Button( -text=>'Pause',
-command=>sub{
$continue_flag = 0;
$mw->after(10000,
sub{ $continue_flag = 1 });

})->pack();


Of course you can work out details, like changing
the text of the Pause button to Continue, or not having
an automatic default 10 second pause.

But this method will not block the GUI, because of the
}else{next} statement keeps the Tk event loop flowing.

>The pause button is at the moment implemented like
>this:
>
>sub pause_button_command {
> if ($continued == 0) {
> $pause_button->configure(-text => "Pause");
> $continued = 1;
> }
> else {
> $continued = 0;
> $pause_button->configure(-text => "Continue");
> $mw->waitVariable($continued);
> }
>}
>



--
I'm not really a human, but I play one on earth.
http://zentara.net/japh.html
Daniel Qarras

2005-10-09, 6:57 pm

zentara wrote:
>
>
> In GUI programs, it's almost always a bad design if you need
> to use a while(1) loop or a sleep() statement. This is because
> it interferes with the Tk event loop, and makes the UI unresponsive.
>
> What you need to do is rethink the design of the loop which
> controls the drawing of the arrows. The easiest way is to use a flag
> variable.


I ended up doing a gross hack that surely ain't following the best Tk or
GUI practices but it works ;) Perhaps I should have mentioned in my
first posting that the arrows are not drawn in a loop but in methods
that are called depending on some user settings, i.e., there's not one
place where the drawing happens but it's bit everywhere so I basically
need to solve this within the pause_flow() method. I also want the
Pause-button to cause the GUI to freeze until the user commands to
continue. But anyway, here's the code, it works, hitting Pause seems to
free the GUI instantly but it's surely horrible looking code :)

sub pause_flow() {
# Wait for 1 second
$sleep_time = 1 * 100;
for (my $i = 0; $i < 10; ++$i) {
__pause_flow($sleep_time);
}
}

sub __pause_flow($) {
# Internal helper method
$mw->update();
$mw->after(@_);
}

Thanks.
Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com