PHP-GTK2 Newsletter

PHP-GTK2 Tips & Techniques
FREE Newsletter
by kksou



Sample Code 465: How to set up a countdown timer - Part 2 - a more accurate timer?
Written by kksou   
Friday, 28 March 2008
Problem

This is in response to Nitro7's post titled "Countdown Timer".

In Part 1, I've presented a solution using Gtk::timeout_add().

However, I find that sometimes when the application or system is too busy, the timeout event doesn't always trigger at exactly one second interval. (Remember all the events always need to line up in an events queue.) As a result, the timer is not too accurate after running for a while.

In this Part 2, I present a more accurate version of the countdown timer as shown below:

How to set up a countdown timer - Part 2 - a more accurate timer?


Solution
  • We make use of the same technique as described in Part 1.
  • The only difference is that when the timer is first started, we take note of the initial time.
  • Thereafter, in the signal handler of the timeout event, we calculate the exact time elapsed since the initial time.
  • Note that in the example below, I still maintain the variable $time_left we had used in Part 1. Take a look at the command window. You can see the difference between the actual time elapsed and $time_left. You have to have a busy system, and you have to let it run for some time, before you can see any noticeable difference.

Sample Code
1   
2   
3   
4   
5   
6   
7   
8   
9   
10   
11   
12   
13   
14   
15   
16   
17   
18   
19   
20   
21   
22   
23   
24   
25   
26   
27   
28   
29   
30   
31   
32   
33   
34   
35   
36   
37   
38   
39   
40   
41   
42   
43   
44   
45   
46   
47   
48   
49   
50   
51   
52   
53   
54   
55   
56   
57   
58   
59   
60   
61   
62   
63   
64   
65   
66   
67   
68   
69   
70   
71   
72   
73   
74   
75   
76   
77   
78   
<?php
$window = new GtkWindow();
$window->set_title($argv[0]);
$window->set_size_request(400, 175);
$window->connect_simple('destroy', array('Gtk','main_quit'));
$window->add($vbox = new GtkVBox());

// display title
$title = new GtkLabel("      Set up a countdown timer\n".
"Part 2 - A more accurate timer");
$title->modify_font(new PangoFontDescription("Times New Roman Italic 10"));
$title->modify_fg(Gtk::STATE_NORMAL, GdkColor::parse("#0000ff"));
$title->set_size_request(-1, 40);
$vbox->pack_start($title, 0, 0);
$vbox->pack_start(new GtkLabel(), 0, 0);

$vbox->pack_start(new GtkLabel('Click the button to start the timer'), 0, 0);
$vbox->pack_start(new GtkLabel('When the time is up, an alert message is displayed.'), 0, 0);
$vbox->pack_start(new GtkLabel(), 0, 0);

$vbox->pack_start($hbox = new GtkHBox(), 0, 0);
$hbox->pack_start($button = new GtkButton('Start timer'), 1, 0);
$vbox->pack_start(new GtkLabel());
$button->connect('clicked', 'start_timer');

$window->show_all();
Gtk::main();

// display an alert dialog box
function alert($msg) {
    $dialog = new GtkDialog('Alert', null, Gtk::DIALOG_MODAL);
    $dialog->set_position(Gtk::WIN_POS_CENTER_ALWAYS);
    $top_area = $dialog->vbox;
    $top_area->pack_start($hbox = new GtkHBox());
    $stock = GtkImage::new_from_stock(Gtk::STOCK_DIALOG_WARNING,
        Gtk::ICON_SIZE_DIALOG);
    $hbox->pack_start($stock, 0, 0);
    $hbox->pack_start(new GtkLabel($msg));
    $dialog->add_button(Gtk::STOCK_OK, Gtk::RESPONSE_OK);
    $dialog->set_has_separator(false);
    $dialog->show_all();
    $dialog->run();
    $dialog->destroy();
}

function start_timer($button) {
    $do_long_task = new DoLongTask();
    $do_long_task->total_time = 1.5 * 60; // note 1
    $do_long_task->time_left = 1.5 * 60; // note 2
    $do_long_task->process_task();
    $do_long_task->timeout_ID = Gtk::timeout_add(1000,
        array(&$do_long_task, 'process_task'));
}

class DoLongTask {

    var $progress;
    var $dialog;
    var $time_left; // note 2
    var $subtask_count = 0;
    var $max_task_count = 10;
    var $timeout_ID;
    var $start_time;

    function DoLongTask() {
        // setup a dialog containing progress bar
        $dialog = new GtkDialog('Timer',
            null, Gtk::DIALOG_MODAL); // create a new dialog
        $top_area = $dialog->vbox;
        $dialog->set_size_request(200, 60);
        $this->progress = new GtkLabel();
        $this->progress->modify_font(new PangoFontDescription("Times New Roman Italic 20"));
        $top_area->pack_start($this->progress);
        $dialog->set_has_separator(false);
        $dialog->show_all(); // show the dialog
        $this->dialog = $dialog; // keep a copy of the dialog ID

        $dialog->connect('delete-event',
  • Note that this is only 70% of the sample code. You have to be a registered member to see the entire sample code. Please login or register.
  • Registration is free and immediate.
  • Have some doubt about the registration? Please read this forum article.
Explanation

The above code is based on How to set up a countdown timer - Part 1?

What's new here:

  1. Set the time in seconds. Here I set it at 1.5 minutes, or 90 seconds.
  2. We maintain these variables we have used in Part 1 so that you can see a difference between the two version. (Note: Please see the command window where it shows the differencces.)
  3. Take note of the initial time.
  4. Calculate the actual time elapsed.

Related Links

User reviews

There are no user reviews yet.

Note: You have to be a registered member to leave a comment. Free registration here.

 
< Prev   Next >

Blog - Forum - Privacy Policy - Contact Us
Copyright © 2006-2008. kksou.com. All Rights Reserved