4. Progress Bars

Progress bars are used to show the status of an operation. They are pretty easy to use, as you will see with the code below. But first lets start out with the calls to create a new progress bar.

$progressbar = Gtk2::ProgressBar->new;

Now that the progress bar has been created we can use it.

Gtk2::ProgressBar->set_fraction($progressbar, $fraction);

The first argument is the progress bar you wish to operate on, and the second argument is the amount "completed", meaning the amount the progress bar has been filled from 0-100%. This is passed to the function as a real number ranging from 0 to 1.

GTK v1.2 has added new functionality to the progress bar that enables it to display its value in different ways, and to inform the user of its current value and its range.

A progress bar may be set to one of a number of orientations using the function

Gtk2::ProgressBar->set_orientation($progressbar, $orientation);

The orientation argument may take one of the following values to indicate the direction in which the progress bar moves:

  'left-to-right'/'GTK_PROGRESS_LEFT_TO_RIGHT'
  'right-to-left'/'GTK_PROGRESS_RIGHT_TO_LEFT'
  'bottom-to-top'/'GTK_PROGRESS_BOTTOM_TO_TOP'
  'top-to-bottom'/'GTK_PROGRESS_TOP_TO_BOTTOM'

As well as indicating the amount of progress that has occured, the progress bar may be set to just indicate that there is some activity. This can be useful in situations where progress cannot be measured against a value range. The following function indicates that some progress has been made.

Gtk2::ProgressBar->pulse($progressbar);

The step size of the activity indicator is set using the following function.

Gtk2::ProgressBar->set_pulse_step($progressbar, $fraction);

When not in activity mode, the progress bar can also display a configurable text string within its trough, using the following function.

Gtk2::ProgressBar->set_text($progressbar, $text);

Note

Note that gtk_progress_set_text() doesn't support the printf()-like formatting of the GTK+ 1.2 Progressbar.

You can turn off the display of the string by calling Gtk2::ProgressBar::set_text() again with undef as second argument.

The current text setting of a progressbar can be retrieved with the following function.

Gtk2::ProgressBar->get_text($progressbar);

Progress Bars are usually used with timeouts or other such functions (see section on Timeouts, I/O and Idle Functions) to give the illusion of multitasking. All will employ the Gtk2::ProgressBar::set_fraction() or Gtk2::ProgressBar::pulse() functions in the same manner.

Here is an example of the progress bar, updated using timeouts. This code also shows you how to reset the Progress Bar.



use Glib qw/TRUE FALSE/;
use Gtk2 '-init';

sub progress_timeout
{
	my $pbar = shift;
	if ($pbar->{activity_mode})
	{
		$pbar->pulse;
	}
	else
	{
		# Calculate the value of the progress bar using the
		# value range set in the adjustment object
		$new_val = $pbar->get_fraction() + 0.01;
		
		$new_val = 0.0 if $new_val > 1.0;
		
		# Set the new value
		$pbar->set_fraction($new_val);
	}

	# As this is a timeout function, return TRUE so that it
	# continues to get called
	return TRUE;
}

# Remove the timer
sub destroy_progress
{
	my $window = shift;

	Glib::Source->remove($window->{pbar}->{timer});
	Gtk2->main_quit;
}

$window = Gtk2::Window->new('toplevel');
$window->set_resizable(TRUE);
$window->signal_connect(destroy => \&destroy_progress);
$window->set_title("Gtk2::ProgressBar");
$window->set_border_width(0);

$vbox = Gtk2::VBox->new(FALSE, 5);
$vbox->set_border_width(10);
$window->add($vbox);
$vbox->show;

# Create a centering alignment object;
$align = Gtk2::Alignment->new(0.5, 0.5, 0, 0);
$vbox->pack_start($align, FALSE, FALSE, 5);
$align->show;

# Create the Gtk2::ProgressBar and attach it to the window reference.
$pbar = Gtk2::ProgressBar->new;
$window->{pbar} = $pbar;
$align->add($pbar);
$pbar->show;

# Add a timer callback to update the value of the progress bar
$pbar->{timer} = Glib::Timeout->add(100, \&progress_timeout, $pbar);

$separator = Gtk2::HSeparator->new;
$vbox->pack_start($separator, FALSE, FALSE, 0);
$separator->show;

# rows, columns, homogeneous
$table = Gtk2::Table->new(2, 3, FALSE);
$vbox->pack_start($table, FALSE, TRUE, 0);
$table->show;

# Add a check button to select displaying of the trough text
$check = Gtk2::CheckButton->new_with_label("Show Text");
$table->attach($check, 0, 1, 0, 1,
		['expand', 'fill'],
		['expand', 'fill'],
		5, 5);
$check->signal_connect(clicked => sub {
		my ($check, $progress) = @_;
		
		if ($progress->get_text)
		{
			$progress->set_text('');
		}
		else
		{
			$progress->set_text('some text');
		}
	}, $pbar);
$check->show;

# Add a check button to toggle activity mode
$pbar->{activity_mode} = 0;
$check = Gtk2::CheckButton->new_with_label("Activity Mode");
$table->attach($check, 0, 1, 1, 2,
		['expand', 'fill'],
		['expand', 'fill'],
		5, 5);
$check->signal_connect(clicked => sub {
		my ($check, $progress) = @_;
		
		$progress->{activity_mode} = not $progress->{activity_mode};
		if ($progress->{activity_mode})
		{
			$progress->pulse;
		}
		else
		{
			$progress->set_fraction(0.0);
		}
	}, $pbar);
$check->show;

# Add a check button to toggle orientation
$check = Gtk2::CheckButton->new_with_label("Right to Left");
$table->attach($check, 0, 1, 2, 3,
		['expand', 'fill'],
		['expand', 'fill'],
		5, 5);
$check->signal_connect(clicked => sub {
		my ($check, $progress) = @_;
		
		$orientation = $progress->get_orientation;
		if    ('left-to-right' eq $orientation)
		{
			$progress->set_orientation('right-to-left');
		}
		elsif ('right-to-left' eq $orientation)
		{
			$progress->set_orientation('left-to-right');
		}
	}, $pbar);
$check->show;

# Add a button to exit the program.
$button = Gtk2::Button->new("Close");
$button->signal_connect_swapped(clicked => sub { $_[0]->destroy; }, $window);
$vbox->pack_start($button, FALSE, FALSE, 0);

# This makes it so the button is the default.
$button->can_default(TRUE);

# This grabs this button to be the default button. Simply hitting the "Enter"
# key will cause this button to activate.
$button->grab_default;
$button->show;

$window->show;

Gtk2->main;

0;