Problem
This is in response to Nitro7's post titled "Countdown Timer".
When a button is pressed in an application, he wants another window to open up that displays a minute and second countdown as shown below:
When the time is up, an alert message will be displayed:
Solution
- We make use of the same technique as described in How to display progress bar while processing long task - Part 2 using_idle_add?
- Instead of displaying a progress bar, we display the remaining time using a GtkLabel.
- Also, note that instead of Gtk::idle_add(), we use a Gtk::timeout_add(), since all we need is an update once every second.
- In this example, when the time is up, I simply display an alert dialog box.
- If you want you can also play a sound file. If you're on windows, you can make use of the technique as described in How to launch external app in winxp without the flashing of cmd window? to call an external application that plays your sound file:
$shell = new COM('WScript.Shell'); $shell->Run('cmd /c start "" "' . $cmd_to_play_sound_file . '"', 0, FALSE); unset($shell);
where $cmd_to_play_sound_file
is the command from system prompt to play your sound file. You can try to put just the name of the sound file here. It should be able to launch the appropriate player automatically.
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 48 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 70 71 74 75 76 77 78 79 80 81 82 85 86 87 88 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 107 108 109 110 111 112 113 114 | <?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 - Part 1"); $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->time_left = 10; // note 1 $do_long_task->process_task(); // note 2 $do_long_task->timeout_ID = Gtk::timeout_add(1000, array(&$do_long_task, 'process_task')); // note 3 } class DoLongTask { var $progress; var $dialog; var $time_left; var $subtask_count = 0; var $max_task_count = 10; var $timeout_ID; 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', array( &$this, "on_delete_event")); } // this is where you process your task function process_task() { $this->progress->set_text(date('i:s', $this->time_left)); // note 4 --$this->time_left; while (Gtk::events_pending()) {Gtk::main_iteration();} if ($this->time_left>=0) { // note 5 return true; // not yet! } else { alert("time's up!"); // note 6 $this->dialog->destroy(); // yes, all done. close the dialog Gtk::timeout_remove($this->timeout_ID); return false; } } // function that is called when user closes the timer function on_delete_event($widget, $event) { $this->dialog->destroy(); Gtk::idle_remove($this->timeout_ID); // any other clean-up that you may want to do return true; } } ?> |
Output
As shown above.Explanation
The above code is based on How to display progress bar while processing long task - Part 2 using_idle_add?
We also make use of the code from How to display a popup alert for required fields - Part 1? to display the alert message.
What's new here:
- Sets the time in seconds. Here I set it at 10 seconds. For 15 minutes, set it as 15*60.
- Display the initial time first.
- Update the timer once every second.
- Display the remaining time.
- Time's up?
- Yes, here we display an alert message. You can replace this with playing of sound file, etc.
Related Links
- How to set up a countdown timer - Part 2 - a more accurate timer?
- How to set up a countdown timer - Part 3 - accurate to hundredth of a second?
- How to set up a stopwatch accurate to hundredth of a second?
- How to display progress bar while processing long task - Part 2 using_idle_add?
- How to display progress bar while processing long task - Part 3 - auto begin processing when program starts?
- How to display a popup alert for required fields - Part 1?
Read more...