Object Oriented PHP-GTK2 - Basics of Timeout Functions Object Oriented PHP-GTK2 - Basics of Timeout Functions
it's me, bob. lol. Object Oriented PHP-GTK2 OOPS

Basics of Timeout Functions

Making an application run a function at regular intervals.

Topic: General PHP-GTK (View All Tutorials)
Keywords: timeout_add interval timer
Updated: 351 Days Ago, 2007/12/16 15:38

Another useful feature of the GTK main loop is to have it automatically execute a function or method at regular intervals. This is done with timeouts, with the static methods of Gtk::timeout_add(int ms, callback func[, mixed args[, ...]]) and Gtk::timeout_remove(int timer). For example, to run a function roughly¹ once every second: Gtk::timeout_add(1000, 'my_function');

This demo application will run two different timers at the same time. The first one will update the time/date once every second. The second timeout will run the progress bar which will fill up to the right and then empty to the right. The progress bar itself means nothing, it is just there to provide a means of animation as a physical manifestation of the GTK timeout.

Timeout Demo Application

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

class bobWindow extends GtkWindow {

    
// note 1
    
private $tid1,$tid2;   // timeout identifiers.
    
private $clocktick;    // clock tick sentinel.
    
private $piter,$pdir;  // progress bar maintenance.

    
public function __construct() {
        
parent::__construct();
        
        
$this->clock = new GtkLabel;
        
$this->bar = new GtkProgressBar;
        
$this->vbox = new GtkVBox;
        
$this->hbox = new GtkHBox;

        
$this->connect_simple('delete-event',array($this,'on_quit'));
        
        
$this->piter 0;
        
$this->pdir false;
        
$this->clocktick true;
        
        
// timeout function for the clock just re-renders it, so might as well
        // use it to initalize the clock display too.
        
$this->on_timeout_one();
        
        
// note 2
        
$this->tid1 Gtk::timeout_add(1000,array($this,'on_timeout_one'));
        
$this->tid2 Gtk::timeout_add(50,array($this,'on_timeout_two'));
        
        
$this->set_size_request(300,-1);
        
$this->set_resizable(false);
        
$this->set_position(Gtk::WIN_POS_CENTER);
        
$this->set_title('GTK Timeout Demo');
        
        
$this->bar->set_pulse_step(0.01);
        
$this->clock->set_justify(Gtk::JUSTIFY_CENTER);
        
        
$this->vbox->pack_start($this->clock,true,true,3);
        
$this->vbox->pack_start($this->bar,true,true,3);
        
$this->hbox->pack_start($this->vbox,true,true,3);
        
$this->add($this->hbox);

        
$this->show_all();
        return;
    }
    
    public function 
on_timeout_one() {

        
// run the clock.    
    
        
$this->clock->set_markup(sprintf(
            
"<span size='x-large' weight='bold'><tt>%s%s%s</tt></span>\n".
            
"<span size='large' style='italic'>%s</span>",
            
date('h'),
            ((
$this->clocktick)?(':'):(' ')),
            
date('i A'),
            
date('l F jS, Y')    
        ));

        
$this->clocktick = !$this->clocktick;        
        
        
// note 3
        
return true;
    }
    
    public function 
on_timeout_two() {
    
        
// run the progress bar.
        // (which is really the progress of nothing)

        
if($this->pdir) { --$this->piter; }
        else { ++
$this->piter; }

        
$this->bar->set_fraction(($this->piter 100));
        
        if(
$this->piter == 100) {
            
// empty bar.
            
$this->bar->set_orientation(Gtk::PROGRESS_RIGHT_TO_LEFT);
            
$this->pdir true;
        } else if(
$this->piter == 0) {
            
// fill bar.
            
$this->bar->set_orientation(Gtk::PROGRESS_LEFT_TO_RIGHT);
            
$this->pdir false;
        }
    
        return 
true;
    }
    
    public function 
on_quit() {
        
$this->hide();
        
Gtk::main_quit();
        return;
    }
}

$window = new bobWindow;

Gtk::main();

$window->destroy();
unset(
$window);

?>

Note 1

This class has some private properties which are just used by the functions that are to do the GUI work, like render the clock and the progress bar. I track every other second for the clock to make the colon blink, and I track the current direction the progress bar is filling so that it can be switched which it reaches the end.

Note 2

Here is where the timeouts are created. The Gtk::timeout_add() method returns a unique ID which you can later use on Gtk::timeout_remove() to manually kill off the timeout if needed. The second parametre (the callback) works just like the signal callbacks do, you pass a string of the function name, or an array with an instance of the object and the string of the method name.

Note 3

Both of the functions used in these timeouts always return true. This is because as long as they return true, they will continue to happen every interval that you specified. Returning void (not returning anything) or returning false will halt and destroy the timer. This is useful if your timeout is checking the status of something, it can automatically terminate after the conditions have been met.

 

End Game

Footnote 1

It is worth nothing the use of the word 'roughly' because as it takes time to things. Let's say we have a 1 second timer and we let it execute 60 times to update a progress bar. After 60 times, it might have taken 60.01 seconds because we wasted time updating the GUI. Also if you get your program caught in a processing loop, unless you manually force pending updates the timeouts will not happen until your processing loop is done.

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 ]