f



Progress bar

OK, here's another thing that's not working as I expect, which is a clear indication I'm not understanding something.

I've set up an indeterminate progress bar to keep the user amused while I do a time consuming operation. My code looks like this:

#!/usr/bin/perl
use Tkx;

my $mw = Tkx::widget->new('.');
my $pb = $mw->new_ttk__progressbar(-orient => 'horizontal',\
                                   -mode => 'indeterminate');
my $bt1 = $mw->new_ttk__button(-text => 'Start', -command -> \&go);

$pb->g_grid('-');
$bt1->g_grid('-');

Tkx::MainLoop;

sub go {
  $pb->start;

# Now go off and do something important

  $pb->stop;
}
#######################

Problem is when I click the "Start" button the program does what it is supposed to, but the progress bar never moves. What am I missing?
0
Colin
1/6/2014 5:58:09 PM
comp.lang.perl.tk 4721 articles. 0 followers. pharrendorf (19) is leader. Post Follow

8 Replies
958 Views

Similar Articles

[PageSpeed] 27

On 2014-01-06, Colin Wu wrote:
>I've set up an indeterminate progress bar to keep the user amused while I do a time consuming operation. My code looks like this:

Erm... so when you fire off "go", it doesn't get back to the MainLoop
until it's finished?

I think that's your problem. The progress bar will only be updated
when the program flow is back at MainLoop.

You can't work in a traditional imperative flow style with an
event-driven toolkit like this. Everything has to come back to the
main event dispatch loop, as often as possible.

If "go" needs to run without interruption, perhaps you'd be better off
with a forked subprocess and IPC?

(Warning: I've never used Tkx, only Tk, but I believe the concepts are
similar.)

Roger
0
Roger
1/6/2014 8:58:44 PM
On Monday, January 6, 2014 3:58:44 PM UTC-5, Roger Bell_West wrote:
> On 2014-01-06, Colin Wu wrote:
>=20
> >I've set up an indeterminate progress bar to keep the user amused while =
I do a time consuming operation. My code looks like this:
>=20
>=20
>=20
> Erm... so when you fire off "go", it doesn't get back to the MainLoop
>=20
> until it's finished?
>=20
>=20
>=20
> I think that's your problem. The progress bar will only be updated
>=20
> when the program flow is back at MainLoop.
>=20
>=20
>=20
> You can't work in a traditional imperative flow style with an
>=20
> event-driven toolkit like this. Everything has to come back to the
>=20
> main event dispatch loop, as often as possible.
>=20
>=20
>=20
> If "go" needs to run without interruption, perhaps you'd be better off
>=20
> with a forked subprocess and IPC?
>=20
>=20
>=20
> (Warning: I've never used Tkx, only Tk, but I believe the concepts are
>=20
> similar.)
>=20
>=20
>=20
> Roger

Hi Roger,

I am fairly new to the event-driven paradigm and so recognize I need to cha=
nge my thinking, but having to fork a process to run some lengthy function =
only to have to then wait for it to finish anyway seems rather round-about =
and unnecessarily complex. The user can not do anything else (in the applic=
ation) while the function is running anyway and all I want to do is give th=
em some feedback.

Thanks for your feedback, though. :)
0
Colin
1/7/2014 2:23:05 PM
On 2014-01-07, Colin Wu wrote:
>I am fairly new to the event-driven paradigm and so recognize I need to change my thinking, but having to fork a process to run some lengthy function only to have to then wait for it to finish anyway seems rather round-about and unnecessarily complex. The user can not do anything else (in the application) while the function is running anyway and all I want to do is give them some feedback.

The core problem I meet in event-driven stuff is that I want to do
something long and complex, but I have to make sure the event loop
keeps getting re-entered so that other things can happen.

As far as I can see, the basic answers are:

(1) Fork into a separate process;

(2) Do something clever with threads (THIS NEVER WORKS);

(3) Break down the long complex thing into smaller things which can be
dispatched in series by the event loop.

For example, if you were iterating through an array, you could write a
fragment to:

- take the first element off the array

- do the clever stuff with it, relatively quickly

- if anything is left in the array, reschedule itself

Roger
0
Roger
1/7/2014 2:57:51 PM
On Tuesday, January 7, 2014 9:57:51 AM UTC-5, Roger Bell_West wrote:
>=20
> The core problem I meet in event-driven stuff is that I want to do
>=20
> something long and complex, but I have to make sure the event loop
>=20
> keeps getting re-entered so that other things can happen.
>=20
>

I guess that makes sense. If my function is busy doing something for a long=
 time the event loop is essentially halted for the duration. I will see wha=
t I can do with your first and 3rd suggestions. Never done anything with th=
reads before and your parenthetical comment is not encouraging. :)

Would be nice if Tk/Tkx were clever enough to periodically halt the callbac=
k that was still running, go through the event loop then resume the callbac=
k. (Note I'm assuming only a single callback running at a time, which is pr=
obably a very dangerous assumption.)

Thanks again.
0
Colin
1/7/2014 4:10:17 PM
Colin Wu schrieb am 07.01.2014 17:10:
> On Tuesday, January 7, 2014 9:57:51 AM UTC-5, Roger Bell_West wrote:
>>
>> The core problem I meet in event-driven stuff is that I want to do
>>
>> something long and complex, but I have to make sure the event loop
>>
>> keeps getting re-entered so that other things can happen.
>>
>>
> 
> I guess that makes sense. If my function is busy doing something for a long time the event loop is essentially halted for the duration. I will see what I can do with your first and 3rd suggestions. Never done anything with threads before and your parenthetical comment is not encouraging. :)
> 
> Would be nice if Tk/Tkx were clever enough to periodically halt the callback that was still running, go through the event loop then resume the callback. (Note I'm assuming only a single callback running at a time, which is probably a very dangerous assumption.)

Another approach is to periodically call

	$mw->update();

in your long running callback, which allows Tk's event loop to process,
well, the events.

Esp. with a Tk::ProgressBar, you can update it's '-variable' whenever
your callback has completed some part of it's work and a following
$mw->update()  will then keep the GUI responsive (if called 'often
enough', of course).

Regards, Horst
-- 
<remove S P A M 2x from my email address to get the real one>
0
Horst
1/7/2014 6:28:38 PM
On Tuesday, January 7, 2014 1:28:38 PM UTC-5, Horst-W. Radners wrote:
> 
> Another approach is to periodically call
> 
> 
> 
> 	$mw->update();
> 
> 
> 
> in your long running callback, which allows Tk's event loop to process,
> 
> well, the events.
> 
> 
> 
> Esp. with a Tk::ProgressBar, you can update it's '-variable' whenever
> 
> your callback has completed some part of it's work and a following
> 
> $mw->update()  will then keep the GUI responsive (if called 'often
> 
> enough', of course).
> 
> 
> 
> Regards, Horst
> 
> -- 
> 
> <remove S P A M 2x from my email address to get the real one>

Thanks, Horst! That did the trick!
0
Colin
1/7/2014 6:40:37 PM
On Tuesday, January 7, 2014 1:28:38 PM UTC-5, Horst-W. Radners wrote:
> 
> Another approach is to periodically call
> 
> 
> 
> 	$mw->update();
> 
> 
> 
> in your long running callback, which allows Tk's event loop to process,
> 
> well, the events.
> 
> 
> 
> Esp. with a Tk::ProgressBar, you can update it's '-variable' whenever
> 
> your callback has completed some part of it's work and a following
> 
> $mw->update()  will then keep the GUI responsive (if called 'often
> 
> enough', of course).
> 
> 
> 
> Regards, Horst
> 
> -- 
> 
> <remove S P A M 2x from my email address to get the real one>

Hi Horst,

Looks like I was premature in declaring $mw->update to be the solution. In fact, it crashes my callback with the message 

  bad option "update": must be cget or configure

The reason it seemed to be working is because the progress bar was doing its Cylon-eye thing (blip going back and forth). My guess is it's because, having crashed out of the callback, we're back in the MainLoop.

I could not find any documentation or references to the update option. Can you point me to it?

Thanks.
0
Colin
1/8/2014 8:05:29 PM
On Wednesday, January 8, 2014 3:05:29 PM UTC-5, Colin Wu wrote:
> 
> Hi Horst,
> 
> 
> 
> Looks like I was premature in declaring $mw->update to be the solution. In fact, it crashes my callback with the message 
> 
> 
> 
>   bad option "update": must be cget or configure
> 
> 
> 
> The reason it seemed to be working is because the progress bar was doing its Cylon-eye thing (blip going back and forth). My guess is it's because, having crashed out of the callback, we're back in the MainLoop.
> 
> 
> 
> I could not find any documentation or references to the update option. Can you point me to it?
> 
> 
> 
> Thanks.

So, after a bit of "googling" in this very same Group, I found that somebody (sorry, don't remember who) had the exact same problem and the equivalent of $mw->update() in Tkx is "Tkx::update()".

0
Colin
1/8/2014 8:47:40 PM
Reply: