Re: Problem setting icon for Gtk2::StatusIcon



Hi January,

The main problem you've got here is that you are using 'sleep'. 
Unfortunately it's a bad way to simulate doing work in a GUI 
application, because it will make the whole application sleep. 
No part of the application (including the GUI) will respond 
to anything during those five seconds. Although various people 
have posted 'it works for me', I'm pretty sure that although 
their icon image is updating, it is completely non-interactive 
99% of the time. They just didn't notice it because the icon
has no interactive features anyway. If you did a menu to it, 
it would not react to clicks etc.

You could fix this by doing something like this instead:

sub do_some_work()
{ 
  my $n=0;
  while($n++ < 500)
  {
    select undef,undef,undef,0.01; #sleep for 100th of one second.
    while( Gtk2->events_pending() ) { Gtk2->main_iteration() ; }
 }
}

and then call do_some_work() instead of 'sleep 5'.
you should then get more sane behaviour out of your test 
application. The main thing here is that Gtk is getting a 
chance to process events many times per second. How often is
up to you. In the example above it will be 100 times per second 
or so, but ten times per second would probably be OK.

For example if you create some test window now with the following 
code before Gtk2->main()

my $window=new Gtk2::Window -toplevel;
my $button=new Gtk2::Button("OK");
$button->signal_connect("clicked", sub { system("date"); });
$window->add($button);
$window->show_all;

you'll see that now you can click OK whenever you like and 
the GUI will still respond properly throughout the five seconds.

The problem with this is it's only going to work as long as you
can split up your work into something that can be done in a loop,
or in several stages, with frequent checks of events_pending etc.
(as in the example above, where the 5 second sleep was broken down
into 500 smaller sleeps).

If you can do that (when you get around to implementing the actual 
work routine), you also have the option of doing those chunks of 
work in an idle callback, as Quentin suggested.

If you can't split it up, then the way to go would be to use another
thread or process and do all your work in that. Then you just 
start the work from the gui thread. The GUI would need to either
communicate with the other thread or process, or watch it so that 
it knows when it's finished. Your update subroutine would simply
check if the status has changed, and if so, it would update the icon.

As far as putting the work into another thread goes, you could
probably use Gtk2 with threads, or put all your work into another
script/program altogether and just execute it from the gtk perl app.
the perl docs for 'perlipc' and 'perlopentut', provide lots of examples
of that.  For example you can set the icon and execute a process, then
change the icon back whenever you get a SIGCHLD signal.

For Gtk2 with threads, using idle functions, I found this thread which
may help:http://www.perlmonks.org/?node_id=741979




hope that helps,
Chris





[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]