Object Oriented PHP-GTK2 - Events Pending - Update the GUI Object Oriented PHP-GTK2 - Events Pending - Update the GUI
it's me, bob. lol. Object Oriented PHP-GTK2 OOPS

Events Pending - Update the GUI

When in a loop you need to explicitly tell the GUI to update.

Topic: General PHP-GTK (View All Tutorials)
Keywords: events_pending update refresh lockup
Updated: 362 Days Ago, 2007/12/06 10:24

In some cases, such as when you are stuck in a processing loop, the GUI will become unresponsive or 'lock up'. This is because on it's own, PHP only has a single thread to work in. There are multiple ways around this, and this way is the most simple. It involves checking for pending events (aka updates waiting) and if they exist, force them out.

<?php
while(Gtk::events_pending() || Gdk::events_pending()) {
    
Gtk::main_iteration_do(true);
}
?>

This while loop is how we do that. You insert this wherever you need to take a break and force the GUI to update.

Progress Eh

 

Refreshing a Progress Bar

#!/usr/bin/php -c/etc/gtk/php.ini
<?php

class bobWindow extends GtkWindow {
    
    public 
$progress;    
    
    public function 
__construct() {
        
parent::__construct();
        
        
$this->progress = new GtkProgressBar;
        
        
$this->set_position(Gtk::WIN_POS_CENTER);
        
$this->set_size_request(420,-1);
        
$this->set_title('Gtk Events Pending');
        
$this->set_border_width(6);
        
$this->connect_simple('delete-event',array($this,'on_quit'));

        
$this->progress->set_fraction(0);

        
$this->add($this->progress);

        
$this->show_all();
        return;
    }
    
    public function 
on_quit() {
        
$this->hide();
        
Gtk::main_quit();
        return;
    }
    
    public function 
run_progress() {
        
$value $this->progress->get_fraction();
        
$value += 0.01;

        
$this->progress->set_fraction(round($value,2));
        
$this->progress->set_text(sprintf('Status: %d%%',($value*100)));

        
// note 1
        
while(Gtk::events_pending() || Gdk::events_pending()) {
            
Gtk::main_iteration_do(true);
        }

        if(
$value 1) {
            return 
true;
        } else {
            return 
false;
        }
    }

}

$w = new bobWindow;
Gtk::timeout_add(100,array($w,'run_progress'));

Gtk::main();

$w->destroy();
unset(
$w);
exit(
0);

?>

Note 1

Here is our events pending loop. After updating the progress bar we should take time to force the updates to the GUI so that the user will see an accurate representation of the progress. Without it, it might not update except for every 10%... it might not even update till it finishes the entire task. Depends how busy the user's CPU is and if GTK was able to squeeze in a cycle. Doing this allows us to make sure it does make it in.

 

End Game

If you need to use the events pending loop multiple times, it might be cleaner to create a new method for it in your root class or something so that you can call it with a single line of code.

<?php
class bob {
    static function 
update_gui() {
        while(
Gtk::events_pending() || Gdk::events_pending()) {
            
Gtk::main_iteration_do(true);
        }
        
        return;
    }
}
?>

<?php
bob
::update_gui();
?>

Did you notice the use of the round() function? If you did, did you wonder why it was there? Logically as the loop progresses we get 0.01, 0.02.... 0.99, 1.0 - which we do - however even as PHP prints "1" for some reason GtkProgressBar was sending Gtk Warnings out about trying to set it to a value higher than 1. My guess is that I have come across a bug in PHP core with an internal loss of precision... I have seen that sort of problem many times in multiple programs on multiple systems written in various languages.

Was this document helpful? I appreciate your feedback.
What are the rules about reusing this code?


i can has web two point ooh // copyright © 2007-2008 bob majdak jr
[ xhtml css | firefox ie7 opera ]