Présentation.
Le contrôle GtkProgressBar permet d'afficher la progression d'une opération quelconque qui prend du temps, afin que l'utilisateur patiente et ne pense pas que le programme soit bloqué.
Utilisation de base.
Création.
Ce contrôle étant comme tous les autres contrôles de GTK+ sa fonction de création est très simple :
 function gtk_progress_bar_new : PGtkWidget;
Modification de la position.
Pour fixer la position de la codice_1, la fonction est :
 procedure gtk_progress_bar_set_fraction(pbar : PGtkProgressBar; fraction : gdouble);
Le paramètre codice_2 est la barre de progression et le paramètre codice_3 est la valeur que l'on veut donner à la barre de progression. Cette valeur doit être comprise entre 0,0 (0 %) et 1,0 (100 %).
Pour connaître la position de la codice_1, la fonction est tout simplement :
 function gtk_progress_bar_get_fraction(pbar : PGtkProgressBar) : gdouble;
La valeur de retour est bien entendu comprise entre 0,0 et 1,0.
Orientation de la barre de progression.
La barre de progression peut être soit verticale, soit horizontale. De plus pour chaque position, l'on peut définir le sens de progression, et tout cela avec cette fonction :
 procedure gtk_progress_bar_set_orientation(pbar : PGtkProgressBar; orientation : TGtkProgressBarOrientation);
Le paramètre codice_5 peut prendre quatre valeurs possible :
Au contraire pour connaître son sens de progression, il faut utiliser la fonction :
 function gtk_progress_bar_get_orientation(pbar : PGtkProgressBar) : TGtkProgressBarOrientation;
Premier programme exemple.
Notre premier exemple, très simple, sera fait d'une fenêtre (bien entendu) avec à l'intérieur une barre de progression (qui évoluera de droite à gauche) et un bouton qui permettra de faire avancer la barre de progression de 10%. Et lorsque la barre de progression sera à 100%, nous la réinitialiserons à 0%.
Voilà le fichier codice_6 :
 program gtk017;
 uses glib2, gtk2;
 procedure OnBtnClick(APWidget : PGtkwidget; AData : pgpointer); cdecl;
 var
 Fraction : GDouble;
 begin
 // Récuperation de la valeur de la barre de progression 
 Fraction := gtk_progress_bar_get_fraction(GTK_PROGRESS_BAR(AData));
 Fraction := Fraction + 0.1;
 if Fraction > 1.0 then
 Fraction := 0.0;
 // Modification de la valeur de la barre de progression 
 gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(AData), Fraction);
 end;
 var
 pFenetre : PGtkWidget;
 pVBox : PGtkWidget;
 pBarreProg : PGtkWidget;
 pBtn : PGtkWidget;
 begin
 gtk_init(@argc, @argv);
 pFenetre := gtk_window_new(GTK_WINDOW_TOPLEVEL);
 gtk_window_set_position(GTK_WINDOW(pFenetre), GTK_WIN_POS_CENTER);
 gtk_window_set_default_size(GTK_WINDOW(pFenetre), 320, 200);
 gtk_container_set_border_width(GTK_CONTAINER(pFenetre), 4);
 gtk_window_set_title(GTK_WINDOW(pFenetre), 'Gtk017 : Barre de progression');
 gtk_signal_connect(pGTKOBJECT(pFenetre), 'destroy', GTK_SIGNAL_FUNC(@gtk_main_quit), NULL);
 pVBox := gtk_vbox_new(TRUE, 0);
 gtk_container_add(GTK_CONTAINER(pFenetre), pVBox);
 // Création de la barre de progression
 pBarreProg := gtk_progress_bar_new;
 gtk_progress_bar_set_orientation(GTK_PROGRESS_BAR(pBarreProg), GTK_PROGRESS_RIGHT_TO_LEFT);
 gtk_box_pack_start(GTK_BOX(pVBox), pBarreProg, TRUE, FALSE, 0);
 pBtn := gtk_button_new_with_label('Ajouter 10 %');
 gtk_box_pack_start(GTK_BOX(pVBox), pBtn, TRUE, FALSE, 5);
 g_signal_connect(pGTKOBJECT(pBtn), 'clicked', GTK_SIGNAL_FUNC(@OnBtnClick), pBarreProg);
 gtk_widget_show_all(pFenetre);
 gtk_main;
 end.
Voilà ce que donne l'exécution du programme codice_7, après 3 clics sur le bouton :
Utilisation dans une boucle.
Problème.
Si nous modifions légèrement le programme précédent pour insérer une boucle qui fera avancer automatiquement la barre de progression (par exemple une boucle de 2000 itérations) cela ne fonctionnera pas. La seule raison pour laquelle cela ne fonctionnera pas est que Gtk+ ne reprend pas la main car le programme reste dans la boucle et ainsi Gtk+ ne peut pas mettre à jour les contrôles affichés.
Solution.
La solution, est de dire clairement à Gtk+ qu’il doit remettre à jour grâce à la fonction suivante :
 function gtk_main_iteration : gboolean;
Cette fonction permet de faire, comme son nom l'indique, une seule itération. Donc à ce moment là Gtk+ va reprendre la main puis la rendre aussitôt, si bien qu’il pourra mettre à jour les contrôles. Il suffit donc d’ajouter cette fonction après codice_8 pour faire fonctionner correctement notre programme.
Ce problème étant réglé, nous allons faire face à un deuxième problème, ou plutôt pseudo-problème. En général, lorsque le programme fait un gros calcul, l’application doit être « bloquée » pendant ce temps. Donc tant que le traitement n’est pas fini, il faut éviter que l’utilisateur ne puisse changer des données. Prenons le cas d’un correcteur d’orthographe, disons qu’il le fasse automatiquement. Pendant qu’il vérifie l’orthographe il serai dommage que l’utilisateur puisse modifier le texte, ce qui fausserait alors toute la correction. Pourquoi cet exemple ? Et bien le fait de rendre la main a Gtk+ lui donne le pouvoir de traiter d’autres évènements, comme un clic de souris et autres. Donc à tout moment pendant ce calcul l’utilisateur peut modifier quelque chose (ici pas grand chose si ce n’est que re-cliquer sur le bouton de démarrage de la boucle), donc il faut pouvoir l’empêcher de faire une quelconque action.
Nous allons pouvoir bloquer l'utilisateur à l'aide de ces deux fonctions :
 procedure gtk_grab_add(widget : PGtkWidget);
 procedure gtk_grab_remove(widget : PGtkWidget);
Nous allons faire une description rapide des ces deux fonctions à l'aide d'un exemple. Prenons le cas ou l'utilisateur fait dans une application (de dessin par exemple) une sélection par glissement, quand il quitte la zone pour atterrir à côté voir en dehors de la fenêtre, la sélection continue, et bien c’est parce que l’application se focalise sur la fenêtre de sélection, c’est un peut ce que fait codice_9. Nous lui donnons un contrôle et seuls les évènements de ce contrôle seront traiter par Gtk+, et cela tant que codice_10 n’a pas été invoqué. Si bien que quand l'utilisateur fait une sélection et qu'il passe au-dessus d’un autre contrôle, il est ignoré.
Voilà maintenant nous avons tout pour que pendant la boucle la barre de progression soit remise à jour sans que l’utilisateur ne puisse cliquer ailleurs.
Programme exemple.
Nous réutilisons donc l'exemple précédent en modifiant la fonction du bouton qui sert maintenant à démarrer la progression de la barre qui sera effectuée dans la fonction de rappel.
Voilà le fichier codice_11 :
 program gtk018;
 uses glib2, gtk2;
 procedure OnBtnClick(APWidget : PGtkwidget; AData : pgpointer); cdecl;
 var
 Fraction : GDouble;
 I : GInt;
 const
 ITotal = 2000;
 begin
 // Initialisation
 gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(AData), 0.0);
 // Ici on « grab » sur la barre de progression pour 2 raisons : 
 // - Cela évite a GTK+ de regarder tous les évènements ce qui rend plus rapide 
 // l'utilisation de gtk_main_iteration() 
 // - On empêche toute action de l'utilisateur 
 gtk_grab_add(PGtkwidget(AData));
 for I := 0 to ITotal do begin
 Fraction := I / ITotal;
 // Modification de la valeur de la barre de progression 
 gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(AData), Fraction);
 // On donne la main a GTK+ 
 gtk_main_iteration;
 end;
 // On supprime le grab sur la barre de progression 
 gtk_grab_remove(PGtkwidget(AData));
 end;
 var
 pFenetre : PGtkWidget;
 pVBox : PGtkWidget;
 pBarreProg : PGtkWidget;
 pBtn : PGtkWidget;
 begin
 gtk_init(@argc, @argv);
 pFenetre := gtk_window_new(GTK_WINDOW_TOPLEVEL);
 gtk_window_set_position(GTK_WINDOW(pFenetre), GTK_WIN_POS_CENTER);
 gtk_window_set_default_size(GTK_WINDOW(pFenetre), 320, 200);
 gtk_container_set_border_width(GTK_CONTAINER(pFenetre), 4);
 gtk_window_set_title(GTK_WINDOW(pFenetre), 'Gtk018 : Barre de progression');
 gtk_signal_connect(pGTKOBJECT(pFenetre), 'destroy', GTK_SIGNAL_FUNC(@gtk_main_quit), NULL);
 pVBox := gtk_vbox_new(TRUE, 0);
 gtk_container_add(GTK_CONTAINER(pFenetre), pVBox);
 // Création de la barre de progression
 pBarreProg := gtk_progress_bar_new;
 gtk_progress_bar_set_orientation(GTK_PROGRESS_BAR(pBarreProg), GTK_PROGRESS_RIGHT_TO_LEFT);
 gtk_box_pack_start(GTK_BOX(pVBox), pBarreProg, TRUE, FALSE, 0);
 pBtn := gtk_button_new_from_stock(GTK_STOCK_REFRESH);
 gtk_box_pack_start(GTK_BOX(pVBox), pBtn, TRUE, FALSE, 5);
 g_signal_connect(pGTKOBJECT(pBtn), 'clicked', GTK_SIGNAL_FUNC(@OnBtnClick), pBarreProg);
 gtk_widget_show_all(pFenetre);
 gtk_main;
 end.
Voilà ce que donne l'exécution du programme codice_12, après clic sur le bouton et quelques dixièmes de secondes (la barre se remplit toute seule de droite à gauche) :