Le programme d'exemple widgetsintervalle.py affiche une fenêtre comprenant trois widgets d'intervalle connectés au même ajustement, ainsi que plusieurs autres widgets par lesquels il est possible de modifier certains des paramètres vus plus haut ou à la section sur les ajustements. Ceci vous permettra de vous faire une idée plus précise de ce que ces paramètres contrôlent dans le widget. La figure 8.1 montre ce que l'on obtient après avoir lancé le programme :
Le code source de widgetsintervalle.py est le suivant :
1 #!/usr/bin/env python 2 3 # exemple widgetsintervalle.py 4 5 import pygtk 6 pygtk.require('2.0') 7 import gtk 8 9 # Ces fonctions sont la pour nous faciliter les choses 10 11 def nouvelle_entree(nom, rappel, donnees=None): 12 entree = gtk.MenuItem(nom) 13 entree.connect("activate", rappel, donnees) 14 entree.show() 15 return entree 16 17 def gradateurs_valeurs_defaut(gradateur): 18 gradateur.set_update_policy(gtk.UPDATE_CONTINUOUS) 19 gradateur.set_digits(1) 20 gradateur.set_value_pos(gtk.POS_TOP) 21 gradateur.set_draw_value(True) 22 23 class WidgetsIntervalle: 24 def modif_position(self, entree, position): 25 # Fixe la position de la valeur pour les deux gradateurs 26 self.gradateurh.set_value_pos(position) 27 self.gradateurv.set_value_pos(position) 28 29 def modif_mode_actu(self, entree, mode): 30 # Fixe le mode d'actualisation pour les deux gradateurs 31 self.gradateurh.set_update_policy(mode) 32 self.gradateurv.set_update_policy(mode) 33 34 def modif_decimales(self, ajust): 35 # Fixe le nombre de decimales pour arrondir la valeur de ajust 36 self.gradateurh.set_digits(ajust.value) 37 self.gradateurv.set_digits(ajust.value) 38 39 def modif_taille_page(self, ajust2, ajust1): 40 # Les valeurs "taille de la page" et "incrementation par page" de l'ajustement 41 # exemple prennent la valeur donnee par le gradateur "Taille de la page". 42 ajust1.page_size = ajust2.value 43 ajust1.page_incr = ajust2.value 44 # Puis on fait emettre le signal "changed" a ajust1 pour reconfigurer tous les 45 # widgets qui lui sont attaches 46 ajust1.emit("changed") 47 48 def affiche_valeur(self, bouton): 49 # Active ou desactive l'affichage de la valeur sur les gradateurs, 50 # en fonction de l'etat du bouton a bascule 51 self.gradateurh.set_draw_value(bouton.get_active()) 52 self.gradateurv.set_draw_value(bouton.get_active()) 53 54 # Construction de notre fenetre exemple 55 56 def __init__(self): 57 # Creation standard d'une fenetre 58 self.fenetre = gtk.Window (gtk.WINDOW_TOPLEVEL) 59 self.fenetre.connect("destroy", gtk.main_quit) 60 self.fenetre.set_title("Widgets d'intervalle") 61 62 boite1 = gtk.VBox(False, 0) 63 self.fenetre.add(boite1) 64 boite1.show() 65 66 boite2 = gtk.HBox(False, 10) 67 boite2.set_border_width(10) 68 boite1.pack_start(boite2, True, True, 0) 69 boite2.show() 70 71 # valeur, minimale, maximale, incr/pas, incr/page, taille de la page 72 # Notez que le parametre "taille de la page" n'a d'effet qu'avec les 73 # barres de defilement, la plus haute valeur etant alors egale a 74 # "maximale" moins "taille de la page" 75 ajust1 = gtk.Adjustment(0.0, 0.0, 101.0, 0.1, 1.0, 1.0) 76 77 self.gradateurv = gtk.VScale(ajust1) 78 gradateurs_valeurs_defaut(self.gradateurv) 79 boite2.pack_start(self.gradateurv, True, True, 0) 80 self.gradateurv.show() 81 82 boite3 = gtk.VBox(False, 10) 83 boite2.pack_start(boite3, True, True, 0) 84 boite3.show() 85 86 # On reutilise le meme ajustement 87 self.gradateurh = gtk.HScale(ajust1) 88 self.gradateurh.set_size_request(200, 30) 89 gradateurs_valeurs_defaut(self.gradateurh) 90 boite3.pack_start(self.gradateurh, True, True, 0) 91 self.gradateurh.show() 92 93 # On reutilise encore le meme ajustement 94 barredefil = gtk.HScrollbar(ajust1) 95 # Notez que l'on demande a ce que les gradateurs soient toujours 96 # actualises en continu quand la barre de defilement est manipulee 97 barredefil.set_update_policy(gtk.UPDATE_CONTINUOUS) 98 boite3.pack_start(barredefil, True, True, 0) 99 barredefil.show() 100 101 boite2 = gtk.HBox(False, 10) 102 boite2.set_border_width(10) 103 boite1.pack_start(boite2, True, True, 0) 104 boite2.show() 105 106 # Un bouton a bascule pour afficher ou pas la valeur 107 bouton = gtk.CheckButton("Afficher la valeur sur les gradateurs") 108 bouton.set_active(True) 109 bouton.connect("toggled", self.affiche_valeur) 110 boite2.pack_start(bouton, True, True, 0) 111 bouton.show() 112 113 boite2 = gtk.HBox(False, 10) 114 boite2.set_border_width(10) 115 116 # Un menu deroulant pour changer la position de la valeur 117 etiquette = gtk.Label("Position de la valeur :") 118 boite2.pack_start(etiquette, False, False, 0) 119 etiquette.show() 120 121 menuderoul = gtk.OptionMenu() 122 menu = gtk.Menu() 123 124 entree = nouvelle_entree ("Au-dessus", self.modif_position, gtk.POS_TOP) 125 menu.append(entree) 126 127 entree = nouvelle_entree ("Au-dessous", self.modif_position, 128 gtk.POS_BOTTOM) 129 menu.append(entree) 130 131 entree = nouvelle_entree ("A gauche", self.modif_position, gtk.POS_LEFT) 132 menu.append(entree) 133 134 entree = nouvelle_entree ("A droite", self.modif_position, gtk.POS_RIGHT) 135 menu.append(entree) 136 137 menuderoul.set_menu(menu) 138 boite2.pack_start(menuderoul, True, True, 0) 139 menuderoul.show() 140 141 boite1.pack_start(boite2, True, True, 0) 142 boite2.show() 143 144 boite2 = gtk.HBox(False, 10) 145 boite2.set_border_width(10) 146 147 # Encore un autre menu deroulant, cette fois-ci pour le mode 148 # d'actualisation des gradateurs 149 etiquette = gtk.Label("Mode d'actualisation :") 150 boite2.pack_start(etiquette, False, False, 0) 151 etiquette.show() 152 153 menuderoul = gtk.OptionMenu() 154 menu = gtk.Menu() 155 156 entree = nouvelle_entree("Continu", self.modif_mode_actu, 157 gtk.UPDATE_CONTINUOUS) 158 menu.append(entree) 159 160 entree = nouvelle_entree ("Discontinu", self.modif_mode_actu, 161 gtk.UPDATE_DISCONTINUOUS) 162 menu.append(entree) 163 164 entree = nouvelle_entree ("Differe", self.modif_mode_actu, 165 gtk.UPDATE_DELAYED) 166 menu.append(entree) 167 168 menuderoul.set_menu(menu) 169 boite2.pack_start(menuderoul, True, True, 0) 170 menuderoul.show() 171 172 boite1.pack_start(boite2, True, True, 0) 173 boite2.show() 174 175 boite2 = gtk.HBox(False, 10) 176 boite2.set_border_width(10) 177 178 # Creation d'un gradateur horizontal pout choisir le nombre de 179 # decimales dans les gradateurs exemples. 180 etiquette = gtk.Label("Decimales :") 181 boite2.pack_start(etiquette, False, False, 0) 182 etiquette.show() 183 184 ajust2 = gtk.Adjustment(1.0, 0.0, 5.0, 1.0, 1.0, 0.0) 185 ajust2.connect("value_changed", self.modif_decimales) 186 gradateur = gtk.HScale(ajust2) 187 gradateur.set_digits(0) 188 boite2.pack_start(gradateur, True, True, 0) 189 gradateur.show() 190 191 boite1.pack_start(boite2, True, True, 0) 192 boite2.show() 193 194 boite2 = gtk.HBox(False, 10) 195 boite2.set_border_width(10) 196 197 # Un dernier gradateur horizontal pour choisir la taille de la page 198 # de la barre de defilement. 199 etiquette = gtk.Label("Taille de la page de la\nbarre de defilement :") 200 boite2.pack_start(etiquette, False, False, 0) 201 etiquette.show() 202 203 ajust2 = gtk.Adjustment(1.0, 1.0, 101.0, 1.0, 1.0, 0.0) 204 ajust2.connect("value_changed", self.modif_taille_page, ajust1) 205 gradateur = gtk.HScale(ajust2) 206 gradateur.set_digits(0) 207 boite2.pack_start(gradateur, True, True, 0) 208 gradateur.show() 209 210 boite1.pack_start(boite2, True, True, 0) 211 boite2.show() 212 213 separateur = gtk.HSeparator() 214 boite1.pack_start(separateur, False, True, 0) 215 separateur.show() 216 217 boite2 = gtk.VBox(False, 10) 218 boite2.set_border_width(10) 219 boite1.pack_start(boite2, False, True, 0) 220 boite2.show() 221 222 bouton = gtk.Button("Quitter") 223 bouton.connect_object("clicked", gtk.main_quit, self.fenetre) 224 boite2.pack_start(bouton, True, True, 0) 225 bouton.set_flags(gtk.CAN_DEFAULT) 226 bouton.grab_default() 227 bouton.show() 228 self.fenetre.show() 229 230 def main(): 231 gtk.main() 232 return 0 233 234 if __name__ == "__main__": 235 WidgetsIntervalle() 236 main()
Vous avez peut-être remarqué que le programme n'appelle pas la méthode connect() pour l'évènement "delete_event", mais seulement pour le signal "destroy", et pourtant tout se passe très bien. Ceci est dû au fait qu'un évènement "delete_event" non traité déclenche automatiquement l'émission du signal "destroy" sur la fenêtre.