IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Apprendre à utiliser le module Python PyGTK 2.0


précédentsommairesuivant

IV. Chapitre 4. Le placement des widgets

Pour créer une application, on aura la plupart du temps, besoin de mettre plusieurs widgets dans la même fenêtre. Notre premier exemple de programme (helloworld.py) n'utilisait qu'un seul widget, nous pouvions donc simplement l'ajouter à la fenêtre avec la méthode de GtkContainer add(). Mais si l'on souhaite mettre plusieurs widgets dans une fenêtre, comment contrôle-t-on la manière dont ils sont placés ? C'est ce que nous allons développer dans ce chapitre.

IV-A. Le principe des boites de placement

Le placement des widgets passe la plupart du temps par la création de boites. Il s'agit de conteneurs invisibles dans lesquels on peut placer nos widgets, et qui existent sous deux formes : la boite horizontale et la boite verticale. Lorsque l'on place des widgets dans une boite horizontale, ceux-ci sont insérés horizontalement, de gauche à droite ou de droite à gauche en fonction de l'appel utilisé. Dans une boite verticale, les widgets sont placés de haut en bas ou inversement. Vous pouvez utiliser toutes les combinaisons de boites que vous voulez à l'intérieur ou à l'extérieur d'autres boites pour obtenir l'effet recherché.

Pour créer une boite horizontale, on fait appel à gtk.HBox(), et pour une boite verticale, à gtk.VBox(). Pour placer des objets dans ces conteneurs, on utilise les méthodes pack_start() et pack_end(). La première les place de haut en bas dans une VBox et de gauche à droite dans une HBox. La seconde fait le contraire : de bas en haut dans une VBox et de droite à gauche dans une HBox. Ces méthodes nous permettent d'aligner nos widgets à gauche ou à droite, et d'obtenir exactement l'effet désiré en les alternant. Nous utiliserons pack_start() dans la majeure partie de nos exemples. Les objets placés à l'intérieur des boites peuvent être des widgets ou de nouveaux conteneurs. En fait, beaucoup de widgets sont déjà eux-mêmes des conteneurs, y compris le bouton (mais on n'utilise généralement qu'une étiquette à l'intérieur d'un bouton).

Grâce à ces appels et à leurs options, GTK sait exactement où et de quelle manière vous voulez placer vos widgets dans le conteneur. De leur définition dépendent de nombreux paramètres comme, par exemple, le redimensionnement automatique. Ces méthodes nous offrent une grande flexibilité dans le placement et la création de nos widgets.

IV-B. Les boites en détail

Du fait même de cette flexibilité, les boites de placement peuvent paraître un peu déroutantes au début. Il y a beaucoup d'options et il n'est pas toujours évident de comprendre leurs effets. Mais en somme, on peut dire qu'il y a cinq styles différents. La figure 4.1 montre ce qu'on obtient en lançant le programme boites.py avec l'argument 1 :

Image non disponible
Figure 4.1. Cinq styles de placement

Chaque ligne contient une boite horizontale comportant plusieurs boutons. L'appel de placement que vous pouvez y lire est un abrégé de celui utilisé pour placer chacun des boutons de la ligne. Tous les boutons d'un même HBox sont placés de la même manière (mêmes arguments pour la méthode pack_start()).

Voici comment s'utilise la méthode pack_start().

 
Sélectionnez
  boite.pack_start(child, expand, fill, padding)

boite est la boite dans laquelle vous allez placer l'objet child (enfant). Pour le moment, les objets seront des boutons. Nous allons donc voir comment placer des boutons dans des boites.

L'argument expand de pack_start() et pack_end() contrôle si les widgets doivent occuper tout l'espace disponible dans la boite (TRUE) — celle-ci s'étirera alors pour remplir la zone qui lui est allouée —, ou si la boite doit au contraire rétrécir jusqu'à la taille minimale nécessaire aux widgets (FALSE). Régler expand sur FALSE vous permettra d'aligner tous vos widgets à droite ou à gauche. Autrement, ils s'étaleront pour occuper tout l'espace de la boite. Le même effet pourrait être obtenu en utilisant uniquement une des deux fonctions pack_start() ou pack_end().

Grâce à l'argument fill, on peut ordonner que l'espace vide autour des widgets leur soit alloué (TRUE). Sinon, on ne touche à rien (FALSE), cet espace jouera le rôle d'un padding supplémentaire autour des objets. fill n'a d'effet que si expand vaut TRUE.

Les fonctions ou méthodes que nous découvrirons tout au long de ce tutoriel peuvent comporter, grâce à Python, des mot-clés et des valeurs par défaut. Le cas échéant, nous les mentionnerons dans la définition de leur fonction, comme à présent avec les méthodes pack_start() et pack_end() :

 
Sélectionnez
1.
2.
3.
  boite.pack_start(child, expand=True, fill=True, padding=0)

  boite.pack_end(child, expand=True, fill=True, padding=0)

child, expand, fill et padding sont des mot-clés (ils apparaitront toujours en gras). On peut remarquer les valeurs par défaut des arguments expand, fill et padding. L'argument child, quant à lui, devra obligatoirement être spécifié.

La création d'une boite ressemble à ceci :

 
Sélectionnez
1.
2.
3.
  boite_h = gtk.HBox(homogeneous=gtk.FALSE, spacing=0)

  boite_v = gtk.VBox(homogeneous=gtk.FALSE, spacing=0)

L'argument homogeneous (homogène) de gtk.HBox() et gtk.VBox() attribue ou pas la même taille à chaque objet dans la boite (la même largeur dans une HBox, ou la même hauteur dans une VBox). S'il vaut TRUE, on obtiendra à peu de choses près le même effet qu'en activant l'argument expand pour chaque objet.

Quelle est la différence entre spacing (défini lors de la création d'une boite) et padding (défini lors du placement d'un objet), qui fixent tous les deux un espacement ? spacing ajoute de l'espace entre les objets, et padding de chaque côté d'un objet. La figure 4.2 illustre cette différence en passant l'argument 2 à boites.py :

Image non disponible
Figure 4.2. Placement avec spacing et padding

La figure 4.3 montre l'utilisation de la méthode pack_end() (passez 3 comme argument à boites.py). L'étiquette "fin" est placée avec cette méthode. Elle colle à l'extrémité droite de la fenêtre, même en cas de redimensionnement.

Image non disponible
Figure 4.3. Placement avec pack_end()

IV-C. Démonstration de placement avec les boites

Voici le code qui a généré les images de la section précédente. Il est assez abondamment commenté, aussi j'espère que vous n'aurez pas de problème à le suivre. Lancez-le et modifiez-le à souhait.

En route pour une brève visite guidée du code :

 
Sélectionnez
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.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
197.
198.
199.
200.
201.
202.
203.
204.
205.
206.
207.
208.
209.
210.
211.
212.
213.
214.
215.
216.
217.
218.
219.
220.
221.
222.
223.
224.
225.
226.
227.
228.
229.
230.
231.
232.
233.
234.
235.
236.
237.
238.
239.
240.
241.
242.
243.
244.
245.
246.
247.
248.
249.
250.
251.
252.
253.
254.
#!/usr/bin/env python

# exemple boite.py

import pygtk
pygtk.require('2.0')
import gtk
import sys, string

# Cette fonction nous aide a créer une nouvelle HBox remplie de boutons+étiquettes.
# Des arguments pour les variables qui nous intéressent lui sont transmis. On n'affiche 
# pas la boite (avec show()), mais on affiche tout ce qui se trouve a l'intérieur.

def creer_boite(homogeneous, spacing, expand, fill, padding):

    # On crée une nouvelle boite avec les valeurs
    # transmises pour "homogeneous" et "spacing"
    boite = gtk.HBox(homogeneous, spacing)

    # On crée une série de boutons, toujours avec les valeurs transmises.
    bouton = gtk.Button("boite.pack")
    boite.pack_start(bouton, expand, fill, padding)
    bouton.show()

    bouton = gtk.Button("(bouton,")
    boite.pack_start(bouton, expand, fill, padding)
    bouton.show()

    # On crée un bouton dont l'étiquette dépendra de la valeur
    # de "expand".
    if expand == True:
        bouton = gtk.Button("True,")
    else:
        bouton = gtk.Button("False,")

    boite.pack_start(bouton, expand, fill, padding)
    bouton.show()

    # Même principe que ci-dessus, mais cette fois avec la
    # formulation abrégée
    bouton = gtk.Button(("False,", "True,")[fill==True])
    boite.pack_start(bouton, expand, fill, padding)
    bouton.show()

    chaine_pad = "%d)" % padding

    bouton = gtk.Button(chaine_pad)
    boite.pack_start(bouton, expand, fill, padding)
    bouton.show()
    return boite

class BoitesPLacement:
    def evnmt_delete(self, widget, evenement, donnees=None):
        gtk.main_quit()
        return False

    def __init__(self, numero):

        # Création de notre fenêtre
        self.fenetre = gtk.Window(gtk.WINDOW_TOPLEVEL)

        # N'oubliez pas de connecter le signal "delete_event"
        # a la fenêtre principale. Cela donne au programme
        # un comportement plus intuitif.
        self.fenetre.connect("delete_event", self.evnmt_delete)
        self.fenetre.set_border_width(10)
    
        # On crée une boite verticale (VBox) pour y placer nos boites
        # horizontales. Ainsi on peut empiler les boites horizontales
        # remplies de boutons les unes sur les autres dans la VBox.
        boite1 = gtk.VBox(False, 0)
    
        # Sur quel scenario partons-nous ? (cf. images de la section 4.2)
        if numero == 1:
            # Création d'une nouvelle etiquette.
            etiquette = gtk.Label("HBox(False, 0)")
    
            # On aligne l'étiquette à gauche. Nous verrons cette méthode
            # ainsi que d'autres dans la section sur les attributs des widgets.
            etiquette.set_alignment(0, 0)

            # On place l'étiquette dans la boite verticale (la VBox boite1).
            # Souvenez-vous que les widgets ajoutés à une VBox seront placés
            # les uns sur les autres, dans l'ordre.
            boite1.pack_start(etiquette, False, False, 0)
    
            # On affiche l'étiquette.
            etiquette.show()
    
            # On appelle notre fonction creer_boite en lui transmettant :
            # homogeneous=False, spacing=0, expand=False, fill=False, padding=0
            boite2 = creer_boite(False, 0, False, False, 0)
            boite1.pack_start(boite2, False, False, 0)
            boite2.show()

            # On appelle notre fonction creer_boite en lui transmettant :
            # homogeneous=False, spacing=0, expand=True, fill=False, padding=0
            boite2 = creer_boite(False, 0, True, False, 0)
            boite1.pack_start(boite2, False, False, 0)
            boite2.show()
    
            # homogeneous=False, spacing=0, expand=True, fill=True, padding=0
            boite2 = creer_boite(False, 0, True, True, 0)
            boite1.pack_start(boite2, False, False, 0)
            boite2.show()
    
            # Création d'un séparateur. On en apprendra plus sur ce widget
            # ultérieurement, mais il est assez simple.
            separateur = gtk.HSeparator()
    
            # On place le séparateur dans la VBox. Gardez bien à l'esprit que
            # tous ces widgets sont placés dans une VBox, ils sont donc
            # empilés les uns sur les autres.
            boite1.pack_start(separateur, False, True, 5)
            separateur.show()
    
            # On crée une autre étiquette, et on l'affiche.
            etiquette = gtk.Label("HBox(True, 0)")
            etiquette.set_alignment(0, 0)
            boite1.pack_start(etiquette, False, False, 0)
            etiquette.show()
    
            # homogeneous=True, spacing=0, expand=True, fill=False, padding=0
            boite2 = creer_boite(True, 0, True, False, 0)
            boite1.pack_start(boite2, False, False, 0)
            boite2.show()
    
            # homogeneous=True, spacing=0, expand=True, fill=True, padding=0
            boite2 = creer_boite(True, 0, True, True, 0)
            boite1.pack_start(boite2, False, False, 0)
            boite2.show()
    
            # Un autre separateur.
            separateur = gtk.HSeparator()
            # Les trois derniers arguments de pack_start() sont :
            # expand, fill, padding.
            boite1.pack_start(separateur, False, True, 5)
            separateur.show()
        elif numero == 2:
            # On crée une étiquette, souvenez-vous que boite1 est une VBox,
            # créée vers le début de __init__()
            etiquette = gtk.Label("HBox(False, 10)")
            etiquette.set_alignment( 0, 0)
            boite1.pack_start(etiquette, False, False, 0)
            etiquette.show()
    
            # homogeneous=False, spacing=10, expand=True, fill=False, padding=0
            boite2 = creer_boite(False, 10, True, False, 0)
            boite1.pack_start(boite2, False, False, 0)
            boite2.show()
    
            # homogeneous=False, spacing=10, expand=True, fill=True, padding=0
            boite2 = creer_boite(False, 10, True, True, 0)
            boite1.pack_start(boite2, False, False, 0)
            boite2.show()
    
            separateur = gtk.HSeparator()
            # Les trois derniers arguments de pack_start() sont :
            # expand, fill, padding.
            boite1.pack_start(separateur, False, True, 5)
            separateur.show()
    
            etiquette = gtk.Label("HBox(False, 0)")
            etiquette.set_alignment(0, 0)
            boite1.pack_start(etiquette, False, False, 0)
            etiquette.show()
    
            # homogeneous=False, spacing=0, expand=True, fill=False, padding=10
            boite2 = creer_boite(False, 0, True, False, 10)
            boite1.pack_start(boite2, False, False, 0)
            boite2.show()
    
            # homogeneous=False, spacing=0, expand=True, fill=True, padding=10
            boite2 = creer_boite(False, 0, True, True, 10)
            boite1.pack_start(boite2, False, False, 0)
            boite2.show()
    
            separateur = gtk.HSeparator()
            # Les trois derniers arguments de pack_start() sont :
            # expand, fill, padding.
            boite1.pack_start(separateur, False, True, 5)
            separateur.show()

        elif numero == 3:

            # Ce scenario est la pour montrer qu'avec pack_end() on peut aligner
            # les widgets à droite. D'abord, créons une boite, comme avant.
            boite2 = creer_boite(False, 0, False, False, 0)

            # on crée l'étiquette que l'on alignera à droite.
            etiquette = gtk.Label("fin")
            # On la place avec pack_end(), elle va se placer à l'extrémité
            # droite de la HBox créée par l'appel à creer_boite().
            boite2.pack_end(etiquette, False, False, 0)
            # On affiche l'étiquette.
            etiquette.show()
    
            # On place boite2 dans boite1
            boite1.pack_start(boite2, False, False, 0)
            boite2.show()
    
            # Un séparateur pour le bas.
            separateur = gtk.HSeparator()
            
            # Cette méthode fixe les dimensions du séparateur (400 pixels de large
            # pour 5 pixels de haut). C'est pour que la HBox qu'on vient de créer
            # fasse aussi 400 de large, et que l'étiquette "fin" soit bien séparée
            # des autres widgets de la HBox. Autrement, tous les widgets de la 
            # HBox seraient placés aussi près l'un de l'autre que possible.
            separateur.set_size_request(400, 5)
            # On place le séparateur dans la HBox (boite1) créée vers le début 
            # de __init__()
            boite1.pack_start(separateur, False, True, 5)
            separateur.show()
    
        # On crée une autre HBox. On peut en utiliser autant qu'on veut !
        boitequitter = gtk.HBox(False, 0)
    
        # Notre bouton "Quitter".
        bouton = gtk.Button("Quitter")
    
        # Lorsque l'on clique sur le bouton, le signal émis doit terminer le programme.
        bouton.connect_object("clicked", gtk.main_quit, self.fenetre)
        # On place le bouton dans la HBox boitequitter.
        # Les trois derniers arguments de pack_start() sont :
        # expand, fill, padding.
        boitequitter.pack_start(bouton, True, False, 0)
        # On place boitequitter dans la VBox (boite1)
        boite1.pack_start(boitequitter, False, False, 0)
    
        # On place la VBox boite1 (qui contient maintenant tous nos widgets)
        # dans la fenêtre principale.
        self.fenetre.add(boite1)
    
        # Et on affiche ce qu'il reste à afficher.
        bouton.show()
        boitequitter.show()
    
        boite1.show()
        # La fenêtre en dernier, afin que tout s'affiche d'un coup.
        self.fenetre.show()

def main():
    # Et bien sûr, notre boucle principale.
    gtk.main()
    # Le contrôle revient ici lorsque main_quit() est appelée.
    return 0         

if __name__ =="__main__":
    if len(sys.argv) != 2:
        sys.stderr.write("La commande doit être de la forme \"boite.py num\", avec num = 1 ou 2 ou 3\n")
        sys.exit(1)
    BoitesPLacement(string.atoi(sys.argv[1]))
    main()

De la ligne 14 à la ligne 50, on définit une fonction creer_boite() qui nous facilitera la création des boites horizontales. À chaque appel, elle créera une HBox et la remplira de cinq boutons en respectant les paramètres spécifiés. Sa valeur de retour est une référence à elle-même.

Puis on définit le constructeur __init__() de la classe BoitesPLacement (lignes 52 à 241), qui crée une fenêtre et une boite verticale enfant. Cette dernière contiendra d'autres widgets dont la nature et la disposition dépendent de l'argument qu'elle reçoit. Si elle reçoit 1, elle crée une fenêtre montrant les cinq arrangements de widgets que l'on peut obtenir en jouant sur les paramètres homogeneous , expand et fill (lignes 75 à 138). Si elle reçoit 2, elle crée une fenêtre qui affiche cette fois-ci les différentes combinaisons de remplissage offertes par les paramètres spacing et padding (lignes 140 à 182). Enfin, en recevant 3, la fenêtre créée par la fonction montrera l'utilisation des méthodes pack_start() et pack_end(), la première pour aligner les boutons à gauche et la seconde pour aligner une étiquette à droite (lignes 188 à 214). Aux lignes 215 à 235, on crée une boite horizontale contenant un bouton, et on la place dans la boite verticale. Le signal "clicked" du bouton est connecté à la fonction PyGTK main_quit() pour terminer le programme.

Aux lignes 250 à 252, on vérifie la ligne de commande : celle-ci doit comporter un seul argument. Dans le cas contraire, on sort du programme avec la fonction sys.exit(). La ligne 253 crée une instance de BoitesPLacement et la ligne 254 invoque la fonction main() qui va initialiser la boucle du réceptionnaire d'événements de GTK.

Dans ce programme exemple, aucune référence de widget n'est enregistrée dans un attribut d'instance (sauf pour la fenêtre). En effet, nos widgets ne seront plus sollicités après leur création.

IV-D. Le placement avec les tableaux

Intéressons-nous à présent à un autre moyen de placer les widgets, qui peut se révéler extrêmement utiles dans certaines occasions : les tableaux.

Avec les tableaux, on crée une grille dans laquelle on peut placer des widgets. Ces derniers peuvent occuper autant d'espace que nous le voulons.

Examinons tout d'abord la fonction gtk.Table() :

 
Sélectionnez
  tableau = gtk.Table(rows=1, columns=1, homogeneous=FALSE)

Le premier argument est le nombre de lignes (rows) souhaitées dans le tableau et le deuxième le nombre de colonnes (columns).

L'argument homogeneous concerne l'homogénéité ou pas des cellules du tableau. S'il vaut TRUE, les cellules feront toutes la même taille : celle du plus grand widget dans le tableau. S'il vaut FALSE, la largeur d'une cellule sera dictée par le widget le plus large de la colonne, et sa hauteur par le widget le plus haut de la ligne.

Les lignes et les colonnes sont numérotées de 0 à n, n étant le nombre spécifié lors de l'appel à gtk.Table(). Donc, en donnant rows=2 et columns=2, on obtient un tableau qui peut être schématisé ainsi :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
       1          2
  0+----------+----------+
   |          |          |
  1+----------+----------+
   |          |          |
  2+----------+----------+

Notez que le système de coordonnées commence dans le coin supérieur gauche. Pour placer un widget dans une cellule, on utilisera la méthode suivante :

 
Sélectionnez
  tableau.attach(child, left_attach, right_attach, top_attach, bottom_attach,
               xoptions=EXPAND|FILL, yoptions=EXPAND|FILL, xpadding=0, ypadding=0)

L'instance tableau est le tableau créé avec gtk.Table(). Le premier paramètre, child (enfant), est le widget que vous souhaitez placer dans le tableau.

Les arguments left_attach (point d'attache gauche), right_attach (point d'attache droit), top_attach (point d'attache haut) et bottom_attach (point d'attache bas) indiquent où placer le widget et combien de cellules il doit occuper. Si l'on veut mettre un bouton dans la cellule inférieure droite de notre tableau 2x2, et s'il ne doit occuper QUE cette cellule, il faudra donner à ces arguments les valeurs suivantes : left_attach = 1, right_attach = 2, top_attach = 1, bottom_attach = 2.

Maintenant, si l'on veut qu'un widget occupe toute la première ligne de notre tableau 2x2, on doit donner left_attach = 0, right_attach = 2, top_attach = 0, bottom_attach = 1.

Les paramètres xoptions et yoptions servent à spécifier une ou plusieurs (avec un OU logique) options de placement.

Ces options sont :

FILL

Si la cellule est plus large que le widget et que FILL est spécifié, le widget s'étirera jusqu'à occuper tout l'espace disponible dans la cellule.

SHRINK

Quand le tableau ne dispose pas de suffisamment d'espace pour afficher les widgets (par exemple, lors d'un redimensionnement de la fenêtre par l'utilisateur), ces derniers sont normalement éjectés vers le bas de la fenêtre et disparaissent. Si SHRINK est spécifié, les widgets rétréciront avec le tableau.

EXPAND

Si cette option est spécifiée, la cellule s'étirera jusqu'à occuper toute la place restant dans l'espace attribué au tableau.

Comme pour les boites de placement, les paramètres de padding créent une zone vide, spécifiée en pixels, autour du widget.

Deux autres méthodes, set_row_spacing() et set_col_spacing(), nous permettent de définir des espacements entre des lignes ou des colonnes :

 
Sélectionnez
  tableau.set_row_spacing(row, spacing)

et

 
Sélectionnez
  tableau.set_col_spacing(column, spacing)

Pour les colonnes (column), l'espacement (spacing) sera appliqué à la droite de la colonne spécifiée ; pour les lignes (rows) ce sera au-dessous de la ligne spécifiée.

On peut aussi fixer en une fois un même espacement pour toutes les lignes et/ou colonnes du tableau :

 
Sélectionnez
  tableau.set_row_spacings(spacing)

et

 
Sélectionnez
  tableau.set_col_spacings(spacing)

Notez qu'avec ces appels la dernière ligne et la dernière colonne ne reçoivent aucun espacement.

IV-E. Démonstration de placement avec les tableaux

Le programme exemple tableaux.py crée une fenêtre avec trois boutons dans un tableau de 2x2. Les deux premiers boutons sont placés sur la ligne du haut. Le troisième, le bouton "Quitter", est placé sur la ligne du bas et occupe les deux colonnes. La figure 4.4 montre la fenêtre obtenue :

Image non disponible
Figure 4.4. Placement avec un tableau

Voici le code source :

 
Sélectionnez
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.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
#!/usr/bin/env python

# exemple tableau.py

import pygtk
pygtk.require('2.0')
import gtk

class Tableau:
    # Notre fonction de rappel. Le paramètre "donnees"
    # transmis a cette méthode est affiché sur stdout
    def salut(self, widget, donnees=None):
        print "Salut ! - Clic sur le %s." % donnees

    # Cette fonction de rappel quitte le programme
    def evnmt_delete(self, widget, evenement, donnees=None):
        gtk.main_quit()
        return False

    def __init__(self):
        # Création d'une nouvelle fenêtre.
        self.fenetre = gtk.Window(gtk.WINDOW_TOPLEVEL)

        # On définit le titre de la fenêtre.
        self.fenetre.set_title("Tableau")

        # On définit un gestionnaire de signal pour "delete_event",
        # qui quitte GTK immédiatement.
        self.fenetre.connect("delete_event", self.evnmt_delete)

        # On fixe la largeur des bordures de la fenêtre.
        self.fenetre.set_border_width(20)

        # Création d'un tableau de 2x2.
        tableau = gtk.Table(2, 2, True)

        # On place le tableau dans la fenêtre principale.
        self.fenetre.add(tableau)

        # Création du premier bouton.
        bouton = gtk.Button("bouton 1")

        # Lorsque l'on clique sur le bouton, la méthode salut() est
        # appelée, avec un pointeur sur "bouton 1" comme argument.
        bouton.connect("clicked", self.salut, "bouton 1")


        # Insertion du bouton 1 dans le quart supérieur gauche du tableau.
        tableau.attach(bouton, 0, 1, 0, 1)

        bouton.show()

        # Création du second bouton.

        bouton = gtk.Button("bouton 2")

        # Lorsque l'on clique sur le bouton, la méthode "salut" est
        # appelée, avec un pointeur sur "bouton 2" comme argument.
        bouton.connect("clicked", self.salut, "bouton 2")
        # Insertion du bouton 2 dans le quart supérieur droit du tableau.
        tableau.attach(bouton, 1, 2, 0, 1)

        bouton.show()

        # Création du bouton "Quitter".
        bouton = gtk.Button("Quitter")

        # Lorsque l'on clique sur le bouton, la fonction mainquit est
        # appelée et le programme se termine.
        bouton.connect("clicked", gtk.main_quit)

        # Insertion du bouton "Quitter" dans les deux quarts inférieurs du tableau.
        tableau.attach(bouton, 0, 2, 1, 2)

        bouton.show()

        tableau.show()
        self.fenetre.show()

def main():
    gtk.main()
    return 0       

if __name__ =="__main__":
    Tableau()
    main()

La classe Tableau est définie de la ligne 9 à la ligne 78.

Aux lignes 12-13, on définit la fonction de rappel salut(), appelée par un clic sur le bouton 1 ou sur le bouton 2. Elle affiche juste un message dans la console qui indique quel bouton a été cliqué, et se sert pour cela de la chaine de caractères qui lui est transmise.

Aux lignes 16-18, on définit la méthode evnmt_delete(), qui est invoquée lorsque le gestionnaire de fenêtres tente de fermer la fenêtre principale.

De la ligne 20 à la ligne 78, on définit __init__(), la méthode constructeur de la classe Tableau. Elle crée une fenêtre (ligne 22), lui donne un titre (ligne 25), connecte la fonction de rappel evnmt_delete() au signal "delete_event" (ligne 29), et fixe les bordures de la fenêtre (ligne 32). Un gtk.Table est créé à la ligne 35 et est ajouté à la fenêtre principale à la ligne 38.

Puis les deux boutons du haut sont créés (lignes 41 et 55), on connecte leurs signaux "clicked" à la méthode salut() (lignes 45 et 59) et on les place dans la première ligne du tableau (lignes 49 et 61). Pour finir, on crée le bouton "Quitter" aux lignes 66 à 73, on connecte son signal "clicked" à la fonction mainquit(), et on le place sur toute l'étendue de la seconde ligne du tableau.


précédentsommairesuivant

Copyright © 2005 John Finlay. Aucune reproduction, même partielle, ne peut être faite de ce site ni de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.