Le conteneur Layout ressemble au conteneur
Fixed à ceci près qu'il implémente
une zone défilable infinie (un infini limité à 2^32). Le système X window
possède une limitation de taille de fenêtre de 32767x32767 pixels. Le
conteneur Layout tourne cette limitation en
réalisant des trucs exotiques utilisant la gravité de fenêtre et de bit.
Il devient ainsi possible d'obtenir un défilement régulier même lorsque
l'on a plein de widgets enfants dans la zone de défilement.
On crée un conteneurLayout par :
affiche = gtk.Layout(hadjustment=None,vadjustment=None)
Comme on peut le constater, il est possible d'indiquer,
de manière facultative, des objets Adjustment,
(voir Chapitre 7, Adjustments) que le widget
Layout va utiliser pour son défilement. Si
l'on ne précise pas d'objets Adjustment, des
nouveaux seront créés automatiquement.
On peut ajouter et déplacer des widgets dans un
conteneur Layout avec les méthodes
suivantes :
affiche.put(widget_enfant,x,y) affiche.move(widget_enfant,x,y)
On peut indiquer ou connaître la taille du conteneur
Layout en utilisant les méthodes :
affiche.set_size(largeur,hauteur) taille = layout.get_size()
Ces quatres dernières méthodes du widget Layout
permettent de manipuler les widgets d'ajustement horizontal et vertical :
horiz_ajust = affiche.get_hadjustment() vert_ajust = affiche.get_vadjustment() affiche.set_hadjustment(ajustement) affiche.set_vadjustment(ajustement)
Le programme
layout.py crée trois boutons et les place dans un
conteneur Layout affiche. Quand on clique sur
l'un des boutons, il est transféré à un nouvel emplacement, aléatoire,
dans le conteneur. La Figure 10.3, « Exemple de conteneur Layout »montre l'affichage de départ.
Voici le code source du programme layout.py :
1 #!/usr/bin/env python
2 # -*- coding:utf-8 -*-
3 # exemple layout.py
4
5 import pygtk
6 pygtk.require('2.0')
7 import gtk
8 import random
9
10 class ExempleAffiche:
11 def WindowDeleteEvent(self, widget, event):
12 # retourne False pour que la fenêtre soit détruite
13 return False
14
15 def WindowDestroy(self, widget, *data):
16 # quitte la boucle principale
17 gtk.main_quit()
18
19 def ButtonClicked(self, bouton):
20 # déplace le bouton
21 self.affiche.move(bouton, random.randint(0,500),
22 random.randint(0,500))
23
24 def __init__(self):
25 # crée la fenêtre de niveau supérieur
26 fenetre = gtk.Window(gtk.WINDOW_TOPLEVEL)
27 fenetre.set_title("Exemple conteneur Layout")
28 fenetre.set_default_size(300, 300)
29 fenetre.connect("delete-event", self.WindowDeleteEvent)
30 fenetre.connect("destroy", self.WindowDestroy)
31 # crée une table et la place dans la fenêtre
32 table = gtk.Table(2, 2, False)
33 fenetre.add(table)
34 # crée le conteneur affiche affiche et le place dans la table
35 self.affiche = gtk.Layout(None, None)
36 self.affiche.set_size(600, 600)
37 table.attach(self.affiche, 0, 1, 0, 1, gtk.FILL|gtk.EXPAND,
38 gtk.FILL|gtk.EXPAND, 0, 0)
39 # crée les barres de défilement et les place dans la table
40 vert_defil = gtk.VScrollbar(None)
41 table.attach(vert_defil, 1, 2, 0, 1, gtk.FILL|gtk.SHRINK,
42 gtk.FILL|gtk.SHRINK, 0, 0)
43 horiz_defil = gtk.HScrollbar(None)
44 table.attach(horiz_defil, 0, 1, 1, 2, gtk.FILL|gtk.SHRINK,
45 gtk.FILL|gtk.SHRINK, 0, 0)
46 # les barres de défilement utilisent les ajustements du conteneur
47 vAdjust = self.affiche.get_vadjustment()
48 vert_defil.set_adjustment(vAdjust)
49 hAdjust = self.affiche.get_hadjustment()
50 horiz_defil.set_adjustment(hAdjust)
51 # crée 3 boutons et les place dans le conteneur
52 bouton = gtk.Button("Clic !")
53 bouton.connect("clicked", self.ButtonClicked)
54 self.affiche.put(bouton, 0, 0)
55 bouton = gtk.Button("Clic !")
56 bouton.connect("clicked", self.ButtonClicked)
57 self.affiche.put(bouton, 100, 0)
58 bouton = gtk.Button("Clic !")
59 bouton.connect("clicked", self.ButtonClicked)
60 self.affiche.put(bouton, 200, 0)
61 # Montre tous les widgets
62 fenetre.show_all()
63
64 def main():
65 # on entre dans la boucle principale
66 gtk.main()
67 return 0
68
69 if __name__ == "__main__":
70 ExempleAffiche()
71 main()