GtkFr - Cours Gtk+-2

PyLaSelectionDeValeursNumeriques

PageAccueil :: LesNews :: Telechargement :: Liens :: Forum :: LeChat :: Contact
DerniersChangements :: DerniersCommentaires :: ParametresUtilisateur :: Vous êtes 38.107.191.94
<< La barre d'état PyGtk La barre de progression >>


La sélection de valeurs numériques

1. Présentation

Nous allons dans ce chapitre étudier trois widgets différents qui vont nous permettre de définir une valeur numérique sans avoir à la saisir au clavier. Le premier widget que nous allons étudier est GtkScrollbar qui se dérive en deux widgets différents, un qui est vertical et l'autre horizontal. Puis nous étudierons le widget GtkScale qui lui aussi se décline en un widget vertical et un horizontal. Et nous terminerons avec le widget GtkSpinButton.

1.1 Hiérarchie

GObject -> GtkObject -> GtkWidget -> GtkEntry -> GtkSpinButton
GObject -> GtkObject -> GtkWidget -> GtkRange -> GtkScale -> GtkHScale
GObject -> GtkObject -> GtkWidget -> GtkRange -> GtkScale -> GtkVScale
GObject -> GtkObject -> GtkWidget -> GtkRange -> GtkScrollbar -> GtkHScrollbar
GObject -> GtkObject -> GtkWidget -> GtkRange -> GtkScrollbar -> GtkVScrollbar

2. Pré requis

Ces trois widgets permettent de choisir une valeur numérique à l'intérieur d'une fourchette de valeurs bien définies. Le fonctionnement similaire de ces trois widgets est rendu possible par l'utilisation de l'objet GtkAdjustment?. Nous allons donc tout d'abord acquérir les notions nécessaires sur ce widget pour comprendre les widgets de sélection.

2.1 Structure de l'objet GtkAdjustment?.

struct _GtkAdjustment
{
GtkObject parent_instance;
gdouble lower;
gdouble upper;
gdouble value;
gdouble step_increment;
gdouble page_increment;
gdouble page_size;
}
La propriété parent_instance nous dit tout simplement que l'objet GtkAdjustment? dérive directement de GtkObject. Les valeurs lower et upper déterminent respectivement la valeur minimale et la valeur maximale que peut prendre le widget qui utilise cet objet. La valeur value donne la valeur actuelle telle qu'elle est définie par le widget. Les valeurs step_increment et page_increment définissent de combien value sera modifiée à chaque fois que l'utilisateur demande d'augmenter ou de diminuer la valeur. Nous verrons la différence entre ces deux valeurs avec l'étude des widgets GtkScrollbar et GtkScale. La dernière propriété page_size définit la taille d'une page, mais là aussi cela deviendra plus clair avec l'étude des widgets qui va suivre.

2.2 Les fonctions de bases

La première classe de base est :
ajustement = gtk.Adjustment(value, lower, upper, step_increment, page_increment, page_size)
Nous retrouvons ici tous les paramètres définis précédemment.

Ensuite pour modifier ou récupérer la valeur actuelle de l'objet, il y a ces deux méthodes :
ajustement.set_value(value)
valeur = ajustement.get_value()
Bien entendu la première méthode change le widget utilisateur pour que sa position représente la valeur value, et la deuxième méthode récupère cette valeur.

Et pour terminer voici la méthode qui permet de modifier les valeurs limites de l'objet :
ajustement.clamp_page(lower, upper)
Nous avons vu l'essentiel des méthodes de l'objet GtkAdjustment?, mais en règle générale, il n'est pas nécessaire de les utiliser, car les widgets qui nécessitent cet objet, ont leurs propres méthodes d'accès et de modification des paramètres.

3. Le widget GtkScrollbar

Comme nous l'avons dit dans la présentation, ce widget se décline en deux variantes différentes :
Mais nous allons voir que mise à part les classes de création, toutes les autres modifications se font avec les mêmes méthodes quel que soit le widget utilisé.

3.1 Création

Voici donc les deux classes de création disponibles :
vscrollbar = gtk.VScrollbar()
hscrollbar = gtk.HScrollbar()
La première crée donc une GtkVScrollbar et la seconde une GtkHScrollbar. De plus, nous voyons qu'il faut obligatoirement un GtkAdjustment? pour définir les paramètres du widget. Il va donc falloir dans un premier temps créer un GtkAdjustment? et définir ses valeurs.

Pour ce qui est des valeurs lower, upper, et value, il n'y a pas de problème. Par contre pour les valeurs step_increment et page_increment, il faut connaître un peu le fonctionnement de ce widget. Regardons d'abord à quoi ressemble un widget GtkHScrollbar.

La zone 1 est en fait l'afficheur de la valeur actuelle prise par la GtkScrollbar. Elle permet aussi de sélectionner une valeur en le déplaçant à l'aide de la souris. Les deux zones 2 permettent de modifier la valeur de la zone 1. Un clic de souris sur une de ces zones modifiera la valeur de plus ou moins la valeur de step_increment. Les zones 3 ont le même objectif que les zones 2 mais cette fois avec une modification de valeur de page_increment.

Il reste encore le dernier paramètre à configurer. Ce dernier, page_size, détermine la taille de la zone 1. Si, par exemple le widget GtkScrollbar a une valeur minimale de 0 et une valeur maximale de 100, et nous définissons page_size comme ayant une valeur de 50, la zone 1 du widget aura une longueur égale à la moitié de celle du widget. Le dernier point sur ce paramètre est qu'il détermine aussi la valeur qu'il faut donner à upper. Ce widget fonctionnant en utilisant des pages, la valeur upper n'est jamais atteinte. Si l'on veut pouvoir choisir une valeur entre 0 et 100 avec un page_size égale à 50, il faudra mettre upper à 150 soit le upper théorique plus page_size.
En effet, ce widget n'a pas comme vocation première de permettre de sélectionner des valeurs numériques mais plutôt l'affichage d'autre widget dont la hauteur (ou la largeur) est supérieure à la zone d'affichage. Ainsi lorsque la barre de sélection est complètement à gauche, la valeur de la GtkScrollbar est bien de 0, mais elle considère qu'elle affiche une zone allant de 0 à page_size (50 dans notre exemple). De ce fait, si la barre de sélection est complètement à droite la valeur de la GtkScrollbar sera égale à upper-page_size et considèrera qu'elle affiche une zone allant de upper-page_size à upper (50 à 100 dans notre exemple). Pour conclure, il faut toujours donner à upper la valeur maximale que nous souhaitons pouvoir sélectionner plus la valeur de page_size.

Nous savons maintenant comment configurer le GtkAdjustment? afin de créer proprement une GtkScrollbar.

3.2 La gestion des valeurs

Nous allons maintenant traiter les méthodes de gestion d'une GtkScrollbar. Pour cela, nous n'allons pas utiliser les widgets GtkHScrollbar et GtkVScrollbar car il n'y a pour chaque widget qu'une seule fonction de création, ni le widget GtkScrollbar car il ne possède aucune méthode, mais le widget GtkRange dont dérive toute cette panoplie.

Tout d'abord pour fixer la valeur d'une GtkScrollbar, nous avons à notre disposition la méthode suivante :
scrollbar.range_set_value(value)
Bien sûr le premier paramètre est la valeur que nous voulons donner à notre GtkScrollbar.

A l'inverse, la méthode nous permettant de connaître la valeur de la GtkScrollbar est :
valeur = scrollbar.get_value(range)

Ensuite le widget GtkRange nous offre la possibilité de modifier les bornes du widget ainsi que les différents pas avec ces deux méthodes :
scrollbar.set_increments(step, page)
scrollbar.set_range(min, max)
La première méthode modifie les pas de modification. Les paramètres step et page correspondent aux paramètres step_increment et page_increment du GtkAdjustment? associé au widget.
La deuxième méthode permet de modifier les valeurs minimale et maximale que le widget peut prendre. Là encore, il faut penser au problème de la valeur maximale pour bien configurer max.

Une autre possibilité pour modifier ces paramètres est de créer un nouveau GtkAdjustment? et de l'associer à la GtkScrollbar avec cette fonction :
scrollbar.set_adjustment(adjustment)

3.3 Programme exemple

Notre premier exemple de ce chapitre va nous permettre de sélection les valeurs RGB que nous souhaitons affecter. La couleur formée par ces valeurs ne sera pas affichée car nous nous contenterons d'afficher ces valeurs dans un label.
Pour modifier les valeurs des labels en fonction des modifications des GtkScrollbar, nous allons capturer le signal "value-changed" de chaque GtkScrollbar.
# -*- Encoding:Latin-1 -*-
import gtk

def main():
   window = gtk.Window(gtk.WINDOW_TOPLEVEL)
   window.set_title("GtkScrollbar")
   window.set_default_size(320, 200)
   window.set_border_width(4)

   main_vbox = gtk.VBox(True, 0)
   window.add(main_vbox)

   frame = gtk.Frame("Rouge")
   main_vbox.pack_start(frame, False, False, 0)
   color_box = gtk.VBox(True, 0)
   frame.add(color_box)

   # Label d'affichage de valeur R
   label = gtk.Label("0")
   color_box.pack_start(label, False, False, 0)
   # Creation d un GtkAdjustment
   adjust = gtk.Adjustment(0, 0, 256, 1, 10, 1)
   # Creation d une scrollbar horizontale
   scrollbar = gtk.HScrollbar(adjust)
   color_box.pack_start(scrollbar, True, True, 0)
   # Connexion du signal pour modification de l affichage
   scrollbar.connect("value-changed", OnScrollbarChange, label)

   # Idem pour G
   frame = gtk.Frame("Vert")
   main_vbox.pack_start(frame, False, False, 0)
   color_box = gtk.VBox(True, 0)
   frame.add(color_box)

   label = gtk.Label("0")
   color_box.pack_start(label, False, False, 0)
   adjust = gtk.Adjustment(0, 0, 256, 1, 10, 1)
   scrollbar = gtk.HScrollbar(adjust)
   color_box.pack_start(scrollbar, True, True, 0)
   scrollbar.connect("value-changed", OnScrollbarChange, label)

   # Idem pour B
   frame = gtk.Frame("Bleu")
   main_vbox.pack_start(frame, False, False, 0)
   color_box = gtk.VBox(True, 0)
   frame.add(color_box)

   label = gtk.Label("0")
   color_box.pack_start(label, False, False, 0)
   adjust = gtk.Adjustment(0, 0, 256, 1, 10, 1)
   scrollbar = gtk.HScrollbar(adjust)
   color_box.pack_start(scrollbar, True, True, 0)
   scrollbar.connect("value-changed", OnScrollbarChange, pLabel)

   window.show_all()
   window.connect("destroy", gtk.main_quit, None)

   gtk.main()

def OnScrollbarChange(widget, data):
   # Recuperation de la valeur de la scrollbar
   value = widget.get_value()
   # Creation du nouveau label
   label = "%d" % value
   # Modification du label
   data.set_text(label)

if __name__ == '__main__':
   main()
Résultat


4. Le widget GtkScale

Les widgets GtkHScale et GtkVScale ont un fonctionnement quasi identique aux widget GtkHScrollbar et GtkVScrollbar mais sont plus simple d'utilisation. Un des avantages de ce widget est qu'il offre la possibilité d'afficher tout seul sa valeur.

4.1 Création

Comme pour les GtkScrollbar, nous pouvons créer des GtkScale à l'aide de GtkAdjustment? avec ces fonctions :
GtkWidget* gtk_vscale_new(GtkAdjustment? *adjustment);
GtkWidget* gtk_hscale_new (GtkAdjustment? *adjustment);
La première fonction crée donc un GtkScale vertical alors la deuxième un GtkScale horizontal.
Mais pour ne pas avoir à créer un objet GtkAdjustment?, les créateurs de GTK+ ont pensé à nous fournir une fonction qui n'en a pas besoin :
GtkWidget* gtk_vscale_new_with_range (gdouble min, gdouble max, gdouble step);
GtkWidget* gtk_hscale_new_with_range (gdouble min, gdouble max, gdouble step);
Avec ces quatre fonctions, la signification de step (ou step_increment si l'on utilise un GtkAdjustment?) est un peu différente car le widget GtkScale n'a pas de bouton fléché comme GtkScrollbar. Cette valeur est utilisée pour un déplacement à l'aide des touches fléchées lorsque le widget a le focus. De plus, si nous n'utilisons pas de GtkAdjustment?, la valeur de page_increment est égale à dix fois celle de step.

4.2 La gestion des valeurs.

Pour récupérer ou fixer les différentes valeurs d'un widget GtkScale il faut, comme pour le widget GtkScrollbar, utiliser les fonctions du widget GtkRange qui ont été décrites plus haut. Nous n'allons donc pas revenir dessus.

4.3 Affichage de la valeur sous forme de label.

Comme nous l'avons dit dans la présentation de ce widget, il s'occupe seul d'afficher et de mettre à jour un label qui affiche la valeur du widget. Par défaut, le label est affiché au-dessus du GtkScale. Etudions les quelques fonctions qui nous sont fournis pour gérer cet affichage.
void gtk_scale_set_draw_value (GtkScale *scale, gboolean draw_value);
gboolean gtk_scale_get_draw_value (GtkScale *scale);
La première fonction nous permet de décider si nous voulons qu'un label s'affiche ou pas. Pour cela il suffit de mettre le paramètre draw_value à TRUE si nous souhaitons qu'il s'affiche ou FALSE si nous ne le souhaitons pas. En ce qui concerne le premier paramètre, il faut utiliser la macro de conversion GTK_SCALE().
La deuxième fonction permet de savoir si le label est affiché ou pas.

Ensuite nous avons la possibilité de gérer le nombre de chiffre après la virgule qui sont affichés :
void gtk_scale_set_digits (GtkScale *scale, gint digits);
gint gtk_scale_get_digits (GtkScale *scale);
Dans la première fonction, digit est bien sûr le nombre de chiffre après la virgule à afficher.

Et pour terminer, nous allons voir comment gérer la position du label par rapport à la barre de sélection :
void gtk_scale_set_value_pos (GtkScale *scale, GtkPositionType? pos);
GtkPositionType? gtk_scale_get_value_pos (GtkScale *scale);
Le paramètre pos (de la première fonction) peut prendre une de ces quatre valeurs :

4.4 Exemple.

Nous allons reprendre l'exemple précédent que nous allons transformer pour l'utilisation de widget GtkHScale ce qui le rendra plus simple. Cependant, pour utiliser les fonctions du widget GtkScale, le premier GtkHScale aura un label au dessus, le second aura un label en dessous et le troisième pas du tout.
#include <stdlib.h>
#include <gtk/gtk.h>

int main(int argc,char **argv)
{
   GtkWidget* pWindow;
   GtkWidget *pMainVBox;
   GtkWidget *pFrame;
   GtkWidget *pLabel;
   GtkWidget *pScale;

   gtk_init(&argc,&argv);

   pWindow = gtk_window_new(GTK_WINDOW_TOPLEVEL);
   gtk_window_set_title(GTK_WINDOW(pWindow), "GtkScale");
   gtk_window_set_default_size(GTK_WINDOW(pWindow), 320, 200);
   gtk_container_set_border_width(GTK_CONTAINER(pWindow), 4);

   pMainVBox = gtk_vbox_new(TRUE, 0);
   gtk_container_add(GTK_CONTAINER(pWindow), pMainVBox);

   pFrame = gtk_frame_new("Rouge");
   /* Creation du widget GtkHScale */
   pScale = gtk_hscale_new_with_range(0, 255, 1);
   gtk_container_add(GTK_CONTAINER(pFrame), pScale);
   gtk_box_pack_start(GTK_BOX(pMainVBox), pFrame, FALSE, FALSE, 0);

   pFrame = gtk_frame_new("Vert");
   pScale = gtk_hscale_new_with_range(0, 255, 1);
   /* Position du label en dessous */
   gtk_scale_set_value_pos(GTK_SCALE(pScale), GTK_POS_BOTTOM);
   gtk_container_add(GTK_CONTAINER(pFrame), pScale);
   gtk_box_pack_start(GTK_BOX(pMainVBox), pFrame, FALSE, FALSE, 0);

   pFrame = gtk_frame_new("Bleu");
   pScale = gtk_hscale_new_with_range(0, 255, 1);
   /* Pas d'affichage du label */
   gtk_scale_set_draw_value(GTK_SCALE(pScale), FALSE);
   gtk_container_add(GTK_CONTAINER(pFrame), pScale);
   gtk_box_pack_start(GTK_BOX(pMainVBox), pFrame, FALSE, FALSE, 0);

   gtk_widget_show_all(pWindow);

   g_signal_connect(G_OBJECT(pWindow), "destroy", G_CALLBACK(gtk_main_quit), NULL);

   gtk_main();

   return EXIT_SUCCESS;
}
Résultat


5. Le widget GtkSpinButton

Ce widget est un peu différent des deux précédents dans le sens ou il s'agit en fait d'un widget GtkEntry et de deux GtkButton assemblés pour former un tout. De plus il permet de sélectionner une valeur soit en utilisant les boutons soit en entrant directement la valeur au clavier. Mais voyons tout cela en détail.

5.1 Création

Il existe là aussi deux fonctions de créations :
GtkWidget* gtk_spin_button_new (GtkAdjustment? *adjustment, gdouble climb_rate, guint digits);
GtkWidget* gtk_spin_button_new_with_range (gdouble min, gdouble max, gdouble step);
La première fonction permet de créer un GtkSpinButton à partir d'un GtkAdjustment?, mais il faut cependant préciser le paramètre climb_rate qui correspond au paramètre step_increment du GtkAdjustment? et digits qui représente le nombre de chiffre après la virgule de la valeur que nous allons pouvoir sélectionner.
La deuxième fonction permet de se passer de GtkAdjustment? car nous fixons les valeurs minimales et maximales (paramètres min et max) ainsi que la valeur de modification avec le paramètre step. En ce qui concerne le nombre de chiffres après la virgule, il sera identique à celui de step.

Pour ce widget, le clavier permet aussi de modifier sa valeur. Les touches fléchées HAUT et BAS permettent de modifier la valeur de step_increment (dans le cas de l'utilisation d'un GtkAdjustment?) ou de step. De plus les touches PAGE_UP et PAGE_DOWN permettent de modifier la valeur de page_increment avec une création utilisant un GtkAdjustment? ou de step*10 dans l'autre cas.

5.2 Gestion des valeurs

Voyons tout d'abord comment récupérer ou modifier la valeur en cours d'un GtkSpinButton à l'aide d'une de ces trois fonctions :
void gtk_spin_button_set_value (GtkSpinButton *spin_button, gdouble value);
gdouble gtk_spin_button_get_value (GtkSpinButton *spin_button);
gint gtk_spin_button_get_value_as_int(GtkSpinButton *spin_button);
La première fonction permet donc de modifier la valeur d'un GtkSpinButton. Il faut pour le premier paramètre utiliser la macro de conversion GTK_SPIN_BUTTON().
La deuxième fonction permet de récupérer la valeur d'un GtkSpinButton tout simplement.
La dernière fonction a le même but que la deuxième mais celle-ci renvoie un entier alors que la deuxième renvoie un double.

Nous pouvons nous occuper du nombre de chiffre après la virgule avec ces deux fonctions :
guint gtk_spin_button_get_digits (GtkSpinButton *spin_button);
void gtk_spin_button_set_digits (GtkSpinButton *spin_button, guint digits);
La première fonction permettant de connaître le nombre de chiffre après la virgule alors que la seconde permet de le modifier.

Et pour terminer voici les fonctions qui permettent de modifier les bornes des valeurs :
void gtk_spin_button_get_range (GtkSpinButton *spin_button, gdouble *min, gdouble *max);
void gtk_spin_button_set_range (GtkSpinButton *spin_button, gdouble min, gdouble max);
Comme d'habitude, la première fonction permet de connaître les bornes du GtkSpinButton et la seconde permet de les modifier.

Mais bien sûr, tout cela peut se modifier à l'aide des GtkAdjustment? avec ces deux fonctions :
GtkAdjustment?* gtk_spin_button_get_adjustment(GtkSpinButton *spin_button);
void gtk_spin_button_set_adjustment (GtkSpinButton *spin_button, GtkAdjustment? *adjustment);

5.3 Exemple

Le programme exemple sera identique aux deux premiers, c'est à dire qu'il va permettre de sélectionner une valeur RGB à l'aide de trois widget GtkSpinButton.

5.4 Programme exemple

#include <stdlib.h>
#include <gtk/gtk.h>

int main(int argc,char **argv)
 {
   GtkWidget* pWindow;
   GtkWidget *pMainVBox;
   GtkWidget *pFrame;
   GtkWidget *pSpin;

   gtk_init(&argc,&argv);

   pWindow = gtk_window_new(GTK_WINDOW_TOPLEVEL);
   gtk_window_set_title(GTK_WINDOW(pWindow), "GtkSpinButton");
   gtk_window_set_default_size(GTK_WINDOW(pWindow), 320, 200);
   gtk_container_set_border_width(GTK_CONTAINER(pWindow), 4);

   pMainVBox = gtk_vbox_new(TRUE, 0);
   gtk_container_add(GTK_CONTAINER(pWindow), pMainVBox);

   pFrame = gtk_frame_new("Rouge");
   /* Creation du widget GtkSpinButton */
   pSpin = gtk_spin_button_new_with_range(0, 255, 1);
   gtk_container_add(GTK_CONTAINER(pFrame), pSpin);
   gtk_box_pack_start(GTK_BOX(pMainVBox), pFrame, FALSE, FALSE, 0);

   pFrame = gtk_frame_new("Vert");
   pSpin = gtk_spin_button_new_with_range(0, 255, 1);
   gtk_container_add(GTK_CONTAINER(pFrame), pSpin);
   gtk_box_pack_start(GTK_BOX(pMainVBox), pFrame, FALSE, FALSE, 0);

   pFrame = gtk_frame_new("Bleu");
   pSpin = gtk_spin_button_new_with_range(0, 255, 1);
   gtk_container_add(GTK_CONTAINER(pFrame), pSpin);
   gtk_box_pack_start(GTK_BOX(pMainVBox), pFrame, FALSE, FALSE, 0);

   gtk_widget_show_all(pWindow);

   g_signal_connect(G_OBJECT(pWindow), "destroy", G_CALLBACK(gtk_main_quit), NULL);

   gtk_main();

   return EXIT_SUCCESS;
}
Résultat



<< La barre d'état PyGtk La barre de progression >>

Il n'y a pas de commentaire sur cette page. [Afficher commentaires/formulaire]
Apinc