Aller au menu - Aller au contenu

Icône PyGTK pur

Avatar
Mise à jour : 31/07/2009
Difficulté : Facile Facile Creative Commons BY-NC-SA
808 visites depuis 7 jours, dont 74 sur ce chapitre classé 153/786
Pour clore cette première partie, nous allons apprendre à coder un programme en PyGTK mais cette fois sans l'aide de Glade.
Sommaire du chapitre :
Icône du chapitre
Chapitre précédent Sommaire Chapitre suivant

Utilité

Depuis le début de ce tuto, je vous rabâche que Glade est un outil génial et vous encourage à vous en servir. Pourquoi donc apprendre à coder avec PyGTK sans glade ? Aurais-je changé d'avis sur un coup de tête ?

Rassurez-vous, ^^ nous continuerons à utiliser Glade tout au long du cours. Mais il faut aussi apprendre à utiliser PyGTK sans faire de détour. Le mieux est de maîtriser les deux façons de faire pour savoir tirer les avantages d'une méthode ou d'une autre selon le contexte !! :-°

Glade est parfait dans le cas d'une GUI statique. Mais imaginez une GUI qui évolue au cours du déroulement du programme... Dans ce cas-là, la meilleure méthode consiste à utiliser Glade pour la base de la GUI (statique) et PyGTK pour ajouter des widgets à la volée (dynamique).

Cette technique devient même obligatoire dans certains cas, par exemple si votre programme doit lister des éléments et les afficher chacun dans un widget qui lui est propre. Vous n'aurez d'autre alternative que de lui faire ajouter ces widgets dynamiquement.

Hello World !

Rien de tel que de sauter directement sur un exemple de code. Voici notre bon vieux script "Hello World !" que j'ai quelque peu modifié. Comme vous vous en doutez, cette version est faite pour fonctionner seule, sans fichier .glade.

Code : Python
 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
#!/usr/bin/python
import pygtk
pygtk.require("2.0")
import gtk

class HelloWorld:
	def __init__(self):
		mainWindow = gtk.Window()
		mainWindow.set_title("Hello World!")
		mainWindow.connect("destroy", self.on_mainWindow_destroy)

		self.myLabel = gtk.Label("Hello")

		myButton = gtk.Button("Mon bouton")
		myButton.connect("clicked", self.on_myButton_clicked)

		vBox = gtk.VBox()
		vBox.pack_start(self.myLabel)
		vBox.pack_start(myButton)

		mainWindow.add(vBox)
		mainWindow.show_all()

	def on_mainWindow_destroy(self, widget):
		gtk.main_quit()

	def on_myButton_clicked(self, widget):
		self.myLabel.set_text("World!")

if __name__ == "__main__":
	HelloWorld()
	gtk.main()


Première remarque : le code n'est pas beaucoup plus long, 32 lignes contre 22. C'est dû au fait que notre programme est tout petit. Sur un programme plus conséquent, la version Glade serait en proportion beaucoup plus courte.

Deuxième remarque : la seule chose qui a changé, c'est le contenu de la fonction __init__. Normal, c'est dans cette dernière qu'on chargeait notre fichier Glade pour en lire le contenu. J'ai donc effacé tout l'ancien code pour le remplacer par le nouveau.

Ce nouveau code fait quatre sortes d'actions :
  • créer des widgets ;
  • configurer ces widgets ;
  • relier leurs signaux à nos fonctions ;
  • imbriquer les widgets les uns dans les autres.

Nous allons étudier en détails chaque ligne du programme.

On crée la fenêtre, et on lui donne un titre :

Code : Python
1
2
mainWindow = gtk.Window()
mainWindow.set_title("Hello World !")


Jusque là, rien de compliqué ! :)

Ensuite nous connectons le signal "destroy" de la fenêtre à la fonction self.on_mainWindow_destroy() qui quitte le programme :

Code : Python
1
mainWindow.connect("destroy", self.on_mainWindow_destroy)


De la façon la plus naturelle qui soit, on crée notre label "Hello" :

Code : Python
1
self.myLabel = gtk.Label("Hello")


J'ai donné à la variable myLabel un nom commençant par "self" pour qu'elle soit accessible à toutes les méthodes de notre classe.

On crée ensuite notre bouton, dont on relie le signal "clicked" à la fonction on_myButton_clicked :

Code : Python
1
2
myButton = gtk.Button("Mon bouton")
myButton.connect("clicked", self.on_myButton_clicked)


Maintenant tous nos widgets semblent avoir été créés. Tous ? Pas vraiment, il reste le conteneur qui va englober le bouton et le label. Comme il est invisible, je l'avais oublié. :p

Code : Python
1
vBox = gtk.VBox()


Voilà qui est fait.

Par ces deux lignes de code, on ajoute le label puis le bouton dans la vBox :

Code : Python
1
2
vBox.pack_start(self.myLabel)
vBox.pack_start(myButton)


Le label en haut, et le bouton en bas :) grâce à la méthode pack_start() de gtk.VBox().

Pour finir, on ajoute notre vBox dans la fenêtre :

Code : Python
1
mainWindow.add(vBox)


La méthode add() est très utile car elle sert à ajouter un widget dans un autre. Elle n'est valable que pour les widgets qui ne peuvent avoir qu'un seul enfant. Les widgets pouvant en contenir plusieurs ont des méthodes bien à eux pour le faire (par exemple pack_start() de gtk.VBox() que nous venons de voir).

Et on rend tous les widgets contenus dans cette fenêtre visibles :

Code : Python
1
mainWindow.show_all()


Voilà pour l'analyse de ce petit script. J'espère que ça vous aura été utile.

Documentation

Je profite de cette partie sur PyGTK pur pour vous initier à la documentation.

PyGTK possède une documentation très fournie, dont la partie la plus importante constitue la liste exhaustive des widgets !

Vous trouverez dans cette liste les constructeurs qui permettent de créer n'importe quel widget directement dans votre code comme nous venons de le voir. Et chose bien plus utile encore, chacun de ces widgets est détaillé, avec toutes ses propriétés, ses méthodes, ses ancêtres, etc.

Parcourir cette documentation vous fournira une vision à la fois globale et détaillée de comment fonctionne GTK+. Je vous conseille d'y plonger le nez dès que vous avez un doute sur comment utiliser tel ou tel widget. De temps en temps, on tombe sur des petits bouts de code très utiles.

Bien sûr, cette documentation n'existe qu'en anglais (à ma connaissance). C'est le cas de la plupart des documentations et c'est pour cette raison qu'il faut un bon niveau d'anglais technique pour exercer la profession de développeur. Pour ceux qui ne parlent pas un mot d'anglais, rassurez-vous tout de même car la seconde partie du cours portera justement sur l'ensemble des widgets et leur utilisation. :)

Comment lire la documentation ?

C'est très bien tout ça, mais, moi, je n'ai pas l'habitude de lire ça. Comment fait-on ?

Je vais vous montrer comment lire cette documentation.
Disons que nous voulons tout savoir sur les boutons : il faut cliquer sur gtk.Button et nous arrivons sur la page qui nous intéresse.

Courte description


Tout en haut, nous avons le nom du widget et, un peu plus bas, nous avons sa description courte ("A pushbutton widget that issues a signal when clicked." qui signifie "Un widget bouton-poussoir qui émet un signal lorsqu'on clique dessus.")

Sommaire


Encore un peu plus bas, dans Synopsis, nous avons des liens qui nous amènent plus bas dans la page. Si on clique sur gtk.Button, nous arrivons à la méthode constructeur. Ici, il est écrit les paramètres que nous pouvons envoyer au constructeur (label, stock et use_underline).
Si nous regardons plus bas, nous pouvons voir ce que sont ces paramètres. On découvre donc que label change le texte du bouton, que stock change le "Stock Id" (je vais revenir sur les "Stock Id" plus tard) et que use_underline permet de souligner le texte du bouton. Pour qu'un caractère dans le label soit souligné, il faut le précéder d'un trait de soulignement (underscore "_") ; vous voyez tout y est écrit.

Les méthodes


Si on clique sur une méthode, nous arrivons à la ... méthode.
Sur le fond gris, nous trouvons le prototype de la méthode.
Sur le fond orange pâle, nous trouvons la description des paramètres.
Et plus bas, il est écrit ce que fait la fonction.

Ancêtres


Remontons tout en haut et décendons jusqu'à "Ancestry" qui nous indique les ancêtres du widget. Nous apprenons que gtk.Button descend de gtk.Bin, qui lui descend de gtk.Container, qui lui descend de gtk.Widget, etc.

Propriétés du widget


Maintenant, descendons à "gtk.Button Properties" qui nous indique les attributs du widget. Ce n'est pas très utile de les connaître, car il existe presque tout le temps des méthodes pour les modifier.

Propriétés des signaux du widget


Ensuite, rendons-nous à "gtk.Button Signal Prototypes", une section très importante, car c'est dans celle-ci que nous apprennons quels signaux existent pour chaque widget. Cliquons sur l'un d'eux, "clicked", par exemple.
Nous arrivons presqu'en bas de la page. Ce qui est important de remarquer ici, c'est la ligne commençant par "def callback(". Il y a les paramètres des fonctions callback (fonction que l'on lie à un widget). Les paramètres sont ensuite décrit plus bas.
Que veut dire "user_param1, ..." ?

Ha oui j'oubliais :p
Reprenons l'exemple plus haut :
Code : Python
1
2
3
self.myLabel = gtk.Label("Hello")
myButton = gtk.Button("Mon bouton")
myButton.connect("clicked", self.on_myButton_clicked)


Nous aurions pu procéder d'une autre façon. Il aurait été possible, en effet, de ne pas mettre self. devant myLabel et transmettre le label à la fonction comment ceci.
Code : Python
1
2
3
4
5
myLabel = gtk.Label("Hello")
myButton = gtk.Button("Mon bouton")
myButton.connect("clicked", self.on_myButton_clicked, myLabel)
[...]
def on_myButton_clicked(self, bouton, myLabel):

Comme vous pouvez le voir "myLabel" a été transmis à la fonction "change_Label" en dernier paramètre.
Pourquoi il y a "..." après de "user_param1" ?

Cela signifie qu'on peut mettre autant de paramètres que l'on veut.

Description


Il nous reste qu'une section à voir. Revenons en haut de la page et descendons jusqu'à "Description". Il s'agit de la description complète (et non, je ne vais pas traduire :-° ).

Q.C.M.

À quoi sert la méthode add() ?
On peut invoquer add() sur...
À quoi sert le self devant certaines variables ?
Quelle classe permet de créer une fenêtre ?
Comment relier un signal à une fonction en PyGTK pur ?
Doit-on forcément préciser la taille d'une gtk.VBox ?

Statistiques de réponses au QCM

Dans cette partie, vous avez vu les deux façons de créer une fenêtre. Et maintenant, attaquons-nous à la deuxième partie qui traite sur les widgets. Vous les verrez tous !
Chapitre précédent Sommaire Chapitre suivant

Partager

Il n'y a pas encore de commentaire pour ce tuto.

Ce tutoriel a été corrigé par les zCorrecteurs.