Example 2

A simple example that shows the usage of a progress bar is shown below.

GTK

The file using the C language bindings to GTK to make this interface layout into a functioning program is below.

/* This program displays a "pulsing" (or whatever it's called)
 * ProgressBar, adds a timeout function to keep it updated, shows how
 * to obtain an individual widget that libglade created, and also
 * manually sets up the callback for the delete_event on the main
 * window so that some data (a glib timer) can be attached to the
 * callback.
 *
 * Note that most programs update progress bars during some kind of
 * function that doesn't return to the main event loop (unlike this
 * simple example).  In that case, you must manually tell gtk to
 * update widgets yourself by calling g_main_context_iteration.  (See
 * example-3.c for an example of doing this in a different context).
 */

#include <gtk/gtk.h>
#include <glib.h>
#include <glade/glade.h>

/* This is the callback for the delete_event, i.e. window closing */
void
inform_user_of_time_wasted (GtkWidget *widget, GdkEvent * event, gpointer data)
{
  /* Get the elapsed time since the timer was started */
  GTimer * timer = (GTimer*) data;
  gulong dumb_API_needs_this_variable;
  gdouble time_elapsed = g_timer_elapsed (timer, &dumb_API_needs_this_variable);

  /* Tell the user how much time they used */
  printf ("You wasted %.2f seconds with this program.\n", time_elapsed);

  /* Free the memory from the timer */
  g_timer_destroy (timer);

  /* Make the main event loop quit */
  gtk_main_quit ();
}

gboolean
update_progress_bar (gpointer data)
{
  gtk_progress_bar_pulse (GTK_PROGRESS_BAR (data));

  /* Return true so the function will be called again; returning false removes
   * this timeout function.
   */
  return TRUE;
}

int
main (int argc, char *argv[])
{
  GladeXML *what_a_waste;

  gtk_init (&argc, &argv);

  /* load the interface */
  what_a_waste = glade_xml_new ("example-2.glade", NULL, NULL);

  /* Get the progress bar widget and change it to "activity mode", i.e. a block
   * that bounces back and forth instead of a normal progress bar that fills
   * to completion.
   */
  GtkWidget *progress_bar = glade_xml_get_widget (what_a_waste, "Progress Bar");
  gtk_progress_bar_pulse (GTK_PROGRESS_BAR (progress_bar));

  /* Add a timeout to update the progress bar every 100 milliseconds or so */
  gint func_ref = g_timeout_add (100, update_progress_bar, progress_bar);

  /* Start the wasted_time_tracker timer, and connect it to the callback */
  GTimer *wasted_time_tracker = g_timer_new ();
  GtkWidget *widget = glade_xml_get_widget (what_a_waste, "WasteTimeWindow");
  g_signal_connect (G_OBJECT (widget), "delete_event",
                    G_CALLBACK (inform_user_of_time_wasted),
                    wasted_time_tracker);

  /* start the event loop */
  gtk_main ();

  /* Remove the timeout function--not that it matters since we're about to end */
  g_source_remove (func_ref);

  return 0;
}

GTKMM

The files using the C++ language bindings to GTK to make this interface layout into a functioning program are below. First, the WasteTimeWindow.h header file:

#ifndef WASTE_TIME_WINDOW_H
#define WASTE_TIME_WINDOW_H

#include <libglademm.h>
#include <gtkmm.h>

class WasteTimeWindow : public Gtk::Window
{
public:
  WasteTimeWindow(BaseObjectType* cobject,
                  const Glib::RefPtr<Gnome::Glade::Xml>& glade_xml);
  virtual ~WasteTimeWindow();

protected:
  virtual bool on_delete_event(GdkEventAny* event);
  bool         update_progress_bar();

  Gtk::ProgressBar* d_progress_bar;
  Glib::Timer       d_wasted_time_tracker;
  sigc::connection  d_timeout_function_connection;
};

#endif // WASTE_TIME_WINDOW_H

Next is the WasteTimeWindow.cc file:

#include "WasteTimeWindow.h"
#include <iostream>

using namespace std;

WasteTimeWindow::WasteTimeWindow(
  BaseObjectType* base_object,
  const Glib::RefPtr<Gnome::Glade::Xml>& glade_xml)
  : Gtk::Window(base_object)
{
  // Get the progress bar widget and change it to "activity mode",
  // i.e. a block that bounces back and forth instead of a normal
  // progress bar that fills to completion.
  glade_xml->get_widget("Progress Bar", d_progress_bar);
  // d_progress_bar = 
  //   dynamic_cast<Gtk::ProgressBar*>(what_a_waste->get_widget("Progress Bar"));
  d_progress_bar->pulse();

  // Add a timeout to update the progress bar every 100 milliseconds or so
  d_timeout_function_connection = Glib::signal_timeout().connect(
    sigc::mem_fun(*this, &WasteTimeWindow::update_progress_bar),
    100);
}

WasteTimeWindow::~WasteTimeWindow()
{
  d_timeout_function_connection.disconnect();
}

bool
WasteTimeWindow::on_delete_event(GdkEventAny* event)
{
  // Tell the user how much time they used
  cout << "You wasted " << d_wasted_time_tracker.elapsed()
       << " seconds with this program." << endl;

  // Calling hide() on an object that was passed to Gtk::Main::Run() causes
  // Gtk:Main::Quit() to be called.
  hide();

  // No other handlers need be called...
  return true;
}

bool
WasteTimeWindow::update_progress_bar()
{
  d_progress_bar->pulse();

  // Return true so the function will be called again; returning false removes
  // this timeout function.
  return true;
}

And finally, here is the example-2.cc file which glues everything together:

/* This program displays a "pulsing" (or whatever it's called)
 * ProgressBar, adds a timeout function to keep it updated, shows how
 * to make a derived widget in conjunction with libglade, demonstrates
 * overloading a function for a signal instead of connecting a
 * separate function to the signal, and show using a glibmm timer.
 *
 * Note that most programs update progress bars during some kind of
 * function that doesn't return to the main event loop (unlike this
 * simple example).  In that case, you must manually tell gtk to
 * update widgets yourself by calling Gtk::MainContext::iteration.
 * (See example-3.cc for an example of doing this in a different
 * context).
 */

#include <gtkmm.h>
#include <libglademm/xml.h>
#include "WasteTimeWindow.h"

using namespace std;

int
main (int argc, char *argv[])
{
  Glib::RefPtr<Gnome::Glade::Xml> what_a_waste;
  Gtk::Main kit(argc, argv);

  // load the interface
  what_a_waste = Gnome::Glade::Xml::create("example-2.glade");

  // Get the main window
  WasteTimeWindow* window;
  what_a_waste->get_widget_derived("WasteTimeWindow", window);

  // start the event loop
  Gtk::Main::run( *window );

  return 0;
}

GTK2-PERL

The file using the perl language bindings to GTK to make this interface layout into a functioning program is below.

#!/usr/bin/perl -w

# This program displays a "pulsing" (or whatever it's called)
# ProgressBar, adds a timeout function to keep it updated, shows how
# to obtain an individual widget that libglade created, and also
# manually sets up the callback for the delete_event on the main
# window so that some data (a glib timer) can be attached to the
# callback.
#
# Note that most programs update progress bars during some kind of
# function that doesn't return to the main event loop (unlike this
# simple example).  In that case, you must manually tell gtk to update
# widgets yourself by calling Glib::MainContext->default->iteration.
# (See example-3.pl for an example of doing this in a different
# context).

use Glib qw(TRUE FALSE);
use Gtk2 '-init';
use Gtk2::GladeXML;
use Time::HiRes qw(gettimeofday tv_interval);

# Just to be pedantic...
use strict;
use vars qw($what_a_waste $worthless_window $progress_bar $wasted_time_tracker);

sub inform_user_of_time_wasted
{
  my (undef, undef, $timer) = @_;  # widget, event are unused
  my $elapsed;

  # Get the elapsed time since the timer was started
  $elapsed = tv_interval ( $timer );

  # Tell the user how much time they used
  printf("You wasted %.2f seconds with this program.\n", $elapsed);

  # Make the main event loop quit
  Gtk2->main_quit;
}

sub update_progress_bar
{
  my ($progress_bar) = @_;
  $progress_bar->pulse;
  return TRUE;
}

  # load the interface
  $what_a_waste = Gtk2::GladeXML->new('example-2.glade');

  # Get the progress bar widget and change it to "activity mode", i.e. a block
  # that bounces back and forth instead of a normal progress bar that fills
  # to completion.
  $progress_bar = $what_a_waste->get_widget('Progress Bar');
  $progress_bar->pulse;

  # Add a timeout to update the progress bar every 100 milliseconds or so
  Glib::Timeout->add(100, \&update_progress_bar, $progress_bar);

  # Start the wasted_time_tracker timer, and connect it to the callback
  $wasted_time_tracker = [gettimeofday];
  $worthless_window = $what_a_waste->get_widget('WasteTimeWindow');
  $worthless_window->signal_connect(delete_event => \&inform_user_of_time_wasted,
                                    $wasted_time_tracker);

  # start the event loop
  Gtk2->main;

PYGTK

The file using the python language bindings to GTK to make this interface layout into a functioning program is below.

#!/usr/bin/env python

# This program displays a "pulsing" (or whatever it's called)
# ProgressBar, adds a timeout function to keep it updated, and shows
# how to obtain an individual widget that libglade created.
#
# Note that most programs update progress bars during some kind of
# function that doesn't return to the main event loop (unlike this
# simple example).  In that case, you must manually tell gtk to update
# widgets yourself by calling gtk.events_pending() and
# gtk.main_iteration().  (See example-3.py for an example of doing
# this in a different context).

import gtk
import gtk.glade
import time

class WasteTimeWindow:
  def __init__(self, glade_file):
    # Parse the glade file
    self.what_a_waste = gtk.glade.XML(glade_file)

    # Get the progress bar widget and change it to "activity mode",
    # i.e. a block that bounces back and forth instead of a normal
    # progress bar that fills to completion.
    self.progress_bar = self.what_a_waste.get_widget("Progress Bar")
    self.progress_bar.pulse()

    # Add a timeout to update the progress bar every 100 milliseconds or so
    self.timeout_handler_id = gtk.timeout_add(100, self.update_progress_bar)

    # Start a timer to see how long the user runs this program
    self.start = time.time()

    # Connect signals specified in the .glade file
    self.what_a_waste.signal_autoconnect(
      {"inform_user_of_time_wasted" : self.inform_user_of_time_wasted })

  # This is the callback for the delete_event, i.e. window closing
  def inform_user_of_time_wasted(self, window, event):
    # Tell the user how much time they used
    print 'You wasted %.2f seconds with this program' % (time.time()-self.start)

    # Remove the timer so that gtk doesn't try to keep updating the progress bar
    gtk.timeout_remove(self.timeout_handler_id)

    # Make the main event loop quit
    gtk.mainquit()

    # No other handlers need be called...
    return gtk.FALSE

  def update_progress_bar(self):
    self.progress_bar.pulse()

    # Return true so the function will be called again; returning
    # false removes this timeout function.
    return gtk.TRUE

# Create the WasteTimeWindow
window = WasteTimeWindow("example-2.glade")

# start the event loop
gtk.main()