gnope php gtk gui gnope.org  

GtkProgressBar example
Goto page 1, 2  Next
 
Post new topic   Reply to topic    gnope.org Forum Index -> PHP GTK2 Beginners
View previous topic :: View next topic  
Author Message
beidlerj



Joined: 10 Feb 2006
Posts: 55
Location: Oregon, USA

PostPosted: Tue Feb 28, 2006 12:32 am    Post subject: GtkProgressBar example Reply with quote

Hi all,

Can anyone point me to a good example of using a GtkProgressBar? All the examples I can find through Google seem to be for PHP-Gtk1, and, as near as I can tell, this class has changed quite a bit in PHP-Gtk2. Besides that, all the examples just iterate through a for loop and use a timeout as their "operation in progress."

I would like to do something like take a list of files and display a progress bar while the lot of them are being copied to another server.

Thanks,

Jeff
Back to top
cweiske



Joined: 08 Dec 2005
Posts: 454
Location: Leipzig/Germany

PostPosted: Tue Feb 28, 2006 12:51 am    Post subject: Reply with quote

The PEAR_Frontend_Gtk2 package has a download dialog that uses a progress bar. You could look there.
http://pear.php.net/package/PEAR_Frontend_Gtk2
Back to top
beidlerj



Joined: 10 Feb 2006
Posts: 55
Location: Oregon, USA

PostPosted: Tue Feb 28, 2006 11:16 pm    Post subject: Reply with quote

Thanks for the link. The code is a little above my skill level, but I got enough out of it to make my own progress bar work. Smile

I don't really understand what goes on when you have
Code:
while (Gtk::events_pending()) {Gtk::main_iteration();}


In my program, I have something like (pseudocode):

foreach (fileToProcess)
copy file to server;
call bar->set_fraction( # of file divided by total number of files);
while (events_pending)...

I would have thought that the program wouldn't even get to execute the while loop until after the copy (or whatever operation is being performed) had finished. Also, "main_iteration" makes it sound like it's going to restart your program from the beginning.
Back to top
cweiske



Joined: 08 Dec 2005
Posts: 454
Location: Leipzig/Germany

PostPosted: Tue Feb 28, 2006 11:31 pm    Post subject: Reply with quote

Quote:
I don't really understand what goes on when you have
Code:
while (Gtk::events_pending()) {Gtk::main_iteration();}


That line makes sure that the user interface is updated.

Whenever you make changes to the GUI itself (change the progress value so that the progress bar itself has to be redrawn), this update information is stored in a queue and not executed immediately.

So to make the changes visible, you need to let the Gtk main loop do its work.
But as you have other things to do (because you are in a complex calculation or something), you want to resume as soon as possible - that is, when no commands are in the Gtk queue any more.

Gtk::events_pending() returns true as long as some commands need to be processed, and Gtk::main_iteration() executes exactly one of them.
Back to top
beidlerj



Joined: 10 Feb 2006
Posts: 55
Location: Oregon, USA

PostPosted: Wed Mar 01, 2006 12:45 am    Post subject: Reply with quote

That helps a little bit. I guess I was thinking about the gtk::main() function incorrectly, probably a leftover idea from C/C++ programming. I had been thinking that gtk::main() meant "start the program", but I guess the PHP interpreter starts execution from the first line of code not in a function, not when it sees the main(). So now, if I understand correctly, gtk::main() is what executes the statements you queued up, telling PHP to create a new window, make it x by y big, fill it with z, then show it, etc. All you were doing before calling gtk::main() was adding those things to the 'to-do' list. Right?

I'm still confused about how the events_pending can be checked if there is still an operation in progress. For example, in my pseudocode above, the bar->set_fraction() adds the bar redraw to the queue of things to be drawn and then the main_iteration() actually does the redraw, correct? But doesn't PHP have to wait for the copy file to server operation to return before it can queue the redraw, check for events, and execute the redraw? How does it happen while the copy statement is still running? Confused
Back to top
cweiske



Joined: 08 Dec 2005
Posts: 454
Location: Leipzig/Germany

PostPosted: Wed Mar 01, 2006 12:52 am    Post subject: Reply with quote

beidlerj wrote:
So now, if I understand correctly, gtk::main() is what executes the statements you queued up, telling PHP to create a new window, make it x by y big, fill it with z, then show it, etc. All you were doing before calling gtk::main() was adding those things to the 'to-do' list. Right?

Right.

Quote:
I'm still confused about how the events_pending can be checked if there is still an operation in progress. For example, in my pseudocode above, the bar->set_fraction() adds the bar redraw to the queue of things to be drawn and then the main_iteration() actually does the redraw, correct? But doesn't PHP have to wait for the copy file to server operation to return before it can queue the redraw, check for events, and execute the redraw? How does it happen while the copy statement is still running? :?

You see it right: the events_pending while loop is executed when copying is finished. After that, the progress bar is updated and the next file is being copied.

So if you have long operations going and don't let update gtk the gui via the loop, your program seems to be "hanging". Just imagine you have 5 files, each of this taking 10 seconds to upload. In this 10 seconds, the user could move the window, move another window above it and show it again - but the gui is crippled, because it isn't redrawn.
Only after the upload of one file is completed (and the main iteration is called to do the update), it is refreshed.

There are two ways to circumvent this problem:
a) use threads, one for copying and one for the gui updates
b) make little chunks that are transferred fast, so that you can update more often

Since PHP itself doesn't support threads, only b) can be used :-)
Back to top
beidlerj



Joined: 10 Feb 2006
Posts: 55
Location: Oregon, USA

PostPosted: Wed Mar 01, 2006 2:43 am    Post subject: Reply with quote

Okay, I understand. Thanks for the help. Cool
Back to top
rgljr



Joined: 10 Apr 2006
Posts: 15
Location: Minnesota, USA

PostPosted: Mon Apr 10, 2006 7:16 am    Post subject: Example of Progress Bar Reply with quote

Here is a working Progress Bar Test Program that works for me.

<?php
if(!class_exists('gtk'))
{
die("Please load the php-gtk2 module in your php.ini\r\n");
}
function quit_routine($dialog)
{
$dialog->destroy();
}
function test_progress() {
$window1 = new GtkWindow();
$window1->set_title("Progress");
$window1->set_size_request(200, 35);
$progress_bar = new GtkProgressBar();
$progress_bar->set_orientation(Gtk::PROGRESS_LEFT_TO_RIGHT);
$window1->add($progress_bar);
$window1->connect("destroy", "quit_routine");
$window1->show_all();

for($i=0;$i<100;$i++) {
$progress_bar->set_fraction((float)($i/100.0));
$progress_bar->set_text($i.'% Complete');
sleep(1);
while (Gtk::events_pending()) {
Gtk::main_iteration();
}
}
quit_routine($window1);
}
$window = new GtkWindow();
$window->set_title("Progress Bar Test");
$window->set_size_request(200, 100);
$button = &new GtkButton('Click for Progress Bar');
$button->connect_simple('clicked', 'test_progress');
$button->show();
$window->add($button);
$window->connect_simple("destroy", array("gtk", "main_quit"));
$window->show_all();
Gtk::main();
?>
Back to top
Quinkink



Joined: 06 Apr 2006
Posts: 5
Location: Grenoble/France

PostPosted: Mon Apr 10, 2006 7:06 pm    Post subject: extra query... Reply with quote

Hello to all,
Thank-you for Gnope... this is my first post.
I have no claim to great programming skills...

My question is about the :
while(gtk::events_pending()) gtk::main_iteration();
loop... How do you quit it correctly?

I get :
Gtk-CRITICAL **: gtk_main_quit: assertion `main_loops != NULL' failed
when I use GTK::main_quit(); with the loop still going.

I'm using a function to have a watch ticking over in a label...

public function update_time(){
while($this->clock){
$text=Date('l d F o - H:i:s');
$this->clock->set_text($text);
while(gtk::events_pending()) gtk::main_iteration();
}
}

Thanks.
Back to top
cweiske



Joined: 08 Dec 2005
Posts: 454
Location: Leipzig/Germany

PostPosted: Mon Apr 10, 2006 7:32 pm    Post subject: Re: extra query... Reply with quote

Quinkink wrote:
while(gtk::events_pending()) gtk::main_iteration();
loop... How do you quit it correctly?

It quits automatically if there are no events pending.

Quote:
Gtk-CRITICAL **: gtk_main_quit: assertion `main_loops != NULL' failed
when I use GTK::main_quit(); with the loop still going.

You didn't start the main loop with Gtk::main()
Back to top
Quinkink



Joined: 06 Apr 2006
Posts: 5
Location: Grenoble/France

PostPosted: Tue Apr 11, 2006 2:02 pm    Post subject: Reply with quote

I'm not sure I get it...
I've made a simple class to emulate my code.
When I close the main window I get the
'main-loops!=NULL' error
thanks for looking,
Quinkink.


<?php
Class Example extends GtkWindow{
private $clock;
/********************************************/
function __construct(){
parent::__construct();
$this->connect('destroy', array($this,'rip'));
$this->set_title(__CLASS__);
//$this->set_border_width(10);

$this->add($this->__create_box());
$this->show_all();
$this->update_time();
}
/********************************************/
private function __create_box(){
$frame = new GtkFrame();
$this->clock = new GtkLabel(TRUE);
$frame->add($this->clock);

return $frame;
}
/*********************************************/
private function update_time(){
while($this->clock){
$time=Date('l d F o - H:i:s');
$this->clock->set_text($time);
while(gtk::events_pending()){gtk::main_iteration();}
}
}
/*********************************************/
public function rip(){
GTK::main_quit();
}
}
new Example();
Gtk::main();
?>
Back to top
Quinkink



Joined: 06 Apr 2006
Posts: 5
Location: Grenoble/France

PostPosted: Fri Apr 14, 2006 10:47 am    Post subject: arg... Reply with quote

OK,
I must be missing some logic... I still get
Gtk-CRITICAL **: gtk_main_quit: assertion `main_loops != NULL' failed
when I quit my application.

Am I doing this a complicated way? Should I be using :
while(gtk::events_pending()) gtk::main_iteration();
to do this? Does anyone have a tip on how to have a clock ticking over in a corner of the main window?

Maybe I'm now posting in the wrong thread...
Back to top
cweiske



Joined: 08 Dec 2005
Posts: 454
Location: Leipzig/Germany

PostPosted: Fri Apr 14, 2006 11:07 am    Post subject: Re: arg... Reply with quote

Quinkink wrote:

I must be missing some logic... I still get
Gtk-CRITICAL **: gtk_main_quit: assertion `main_loops != NULL' failed
when I quit my application.


Simple: You start the main loop on the last line of your file, after instantiating the example. In your example, you call the update_time method that calls the iteration loop. Since the main loop hasn't been started yet, it can't find any loop and gives the warning.

You should add a timeout that calls the update_time method instead calling it by hand, then it would work.
Back to top
Quinkink



Joined: 06 Apr 2006
Posts: 5
Location: Grenoble/France

PostPosted: Fri Apr 14, 2006 2:17 pm    Post subject: thx... it works Reply with quote

<?php
Class Example extends GtkWindow{
private $timeout;
private $clock;
/********************************************/
function __construct(){
parent::__construct();
$this->connect('destroy', array($this,'rip'));
$this->set_title(__CLASS__);
//$this->set_border_width(10);

$this->add($this->__create_box());
$this->show_all();
$this->timeout = Gtk::timeout_add(100,array($this,'update_time'));
}
/********************************************/
private function __create_box(){
$frame = new GtkFrame();
$this->clock = new GtkLabel(TRUE);
$frame->add($this->clock);

return $frame;
}
/*********************************************/
public function update_time(){
Gtk::timeout_remove($this->timeout);
while($this->clock){
$time=Date('l d F o - H:i:s');
$this->clock->set_text($time);
while(gtk::events_pending()){gtk::main_iteration();}
}
}
/*********************************************/
public function rip(){
$this->clock=FALSE;
GTK::main_quit();
}
}
new Example();
Gtk::main();
?>
Thanks for the tip, I guess the time out gives the main loop a chance to start befor the other loop kicks in. Here is the updated code in case it helps beginers like me...
Thanks again,
Back to top
scott



Joined: 16 Feb 2006
Posts: 35

PostPosted: Fri Apr 14, 2006 5:29 pm    Post subject: Re: thx... it works Reply with quote

Quinkink wrote:
Thanks for the tip, I guess the time out gives the main loop a chance to start befor the other loop kicks in. Here is the updated code in case it helps beginers like me...


Actually the timeout calls the update_time() method evrey 100 milliseconds. You could updated your code to something like this:
Code:
public function update_time()
{
  $time=Date('l d F o - H:i:s');
  $this->clock->set_text($time);
}

You may still need the events_pending loop. I haven't tested this.

You should also set the timeout length to 1000 mililseconds (1 second) since you aren't showing anything less than that.
Back to top
Display posts from previous:   
Post new topic   Reply to topic    gnope.org Forum Index -> PHP GTK2 Beginners All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group
Templates enhanced by DigiWiki. Hosting by Tradebit.