|
Problem You have displayed a progress bar while processing a long task in Part 1.
However, the problem with that method is that if the user closes the progress bar dialog in the midst of the long task, the dialog disappears, but the process continues in the background. The whole application will appear to "hang" until the long task completes. This is undesirable.
A more "elegant" method to display progress bar while processing a long task is to use the Gtk::idle_add as described below:

Solution
- Just before the long task is started, first set up a dialog that contains a GtkProgressBar.
- Then begin the task by setting up Gtk::idle_add to call your function (that process the long task) whenever it's idle.
- Every time php-gtk has nothing to do, it will make a trip to your function. In your function, do whatever subtask you want to do. If there are more tasks to be completed, return a
true. If all tasks are completed, return a false.
- When all tasks is completed, you should also call Gtk::idle_remove to let php-gtk know that you're done. Of course, you may also want to close the progress bar dialog.
- To trap the event in which the user closes the progress bar dialog, we set up a connect('delete-event').
- When the user closes the progress bar in the midst of the long task, just like above, we call Gtk::idle_remove then close the progress bar dialog.
- As explained in Part 1, don't forget to call
while (Gtk::events_pending()) {Gtk::main_iteration();} so that the progress bar gets updated.
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
| <?php $window = new GtkWindow(); $window->set_size_request(400, 175); $window->connect_simple('destroy', array('Gtk','main_quit')); $window->add($vbox = new GtkVBox());
// display title
$title = new GtkLabel("Display progress bar ". "while processing long task - Part 2"); $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); // add a small gap
$vbox->pack_start(new GtkLabel('using Gtk::idle_add()'), 0, 0); $vbox->pack_start(new GtkLabel('you can also interrupt the long task'), 0, 0); $vbox->pack_start(new GtkLabel(), 0, 0); // add a small gap
$vbox->pack_start($hbox = new GtkHBox(), 0, 0); $hbox->pack_start($button = new GtkButton('Start processing'), 1, 0); $vbox->pack_start(new GtkLabel()); // add a small gap
$button->connect('clicked', 'start_processing');
$window->show_all(); Gtk::main();
function start_processing($button) { $do_long_task = new DoLongTask(); // note 1
$do_long_task->idle_ID = Gtk::idle_add( array(&$do_long_task, 'process_task')); // note 2
}
class DoLongTask { // note 1
var $progress_bar; var $dialog; var $subtask_count = 0; var $max_task_count = 10; var $idle_ID;
function DoLongTask() { // setup a dialog containing progress bar
$dialog = new GtkDialog('Work in progress...', null, Gtk::DIALOG_MODAL); // create a new dialog
$top_area = $dialog->vbox; $top_area->pack_start(new GtkLabel( 'Please hold on while processing data...')); $this->progress_bar = new GtkProgressBar(); $this->progress_bar->set_orientation(Gtk::PROGRESS_LEFT_TO_RIGHT); $top_area->pack_start($this->progress_bar, 0, 0); $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")); // note 3
}
// this is where you process your task
function process_task() { echo "processing subtask $this->subtask_count: "; for ($i=0; $i<10; ++$i) { usleep(50000); // sleep for half a second
print "."; } print "\n";
|
- 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
- Wrap this in a class to avoid any global variables.
- Ask php-gtk to process your long task whenever it's free.
- Let us know if user closes the progress bar dialog.
- Update the percent value.
- Update the displayed text.
- Don't forget this so that progress bar gets updated.
Related Links
User reviews Average user ratings: 3.5 (from 8 users) Note: You have to be a registered member to leave a comment. Free registration here. |
March 15, 2007 1:28am
Nice
February 24, 2008 6:28am
June 27, 2008 10:15am
July 11, 2008 1:25am
September 02, 2008 9:18am
September 08, 2008 1:29pm
March 07, 2009 4:32pm
May 12, 2010 2:31am