P
'
t
i
t
e
C
h
a
t
t
e
 
spacer~ ALL YOUR BASE ARE BELONG TO US Articles | Connexion
 
~Un bloc-notes avec PyQT

Précédent  
  Python  
  Suivant
 Présentation

L'article du mois dernier nous a permis de découvrir la notion de réceptacles et de signaux. Nous allons aujourd'hui mettre à profit nos connaissances pour réaliser une véritable application. Et par souci d'originalité, nous nous proposons de programmer un petit éditeur de texte.
 Sommaire


 Introduction

Un utilitaire d'édition de texte doit offrir certaines fonctionnalités vitales. Parmi celles-ci nous pouvons citer l'ouverture d'un fichier, la création d'un nouveau fichier et la sauvegarde du document. Le développement de l'outil QtEd nécessite l'emploi de quatre composants graphiques QT : la barre de menus, la barre d'outils, la zone de texte et la barre de statut.


 Interface générale

La classe principale de l'application dérive de la classe QMainWindow qui permet de définir une fenêtre décorée (c'est à dire avec des bordures et une barre titre). Cette classe se révèle intéressante à plus d'un titre puisque son API propose des facilités de création pour les barres de menus, d'outils et de statut. Nous sommes aussi en mesure de spécifier le composant "central" de la fenêtre, soit le composant autour duquel seront positionnées les différentes barres. Notez également que l'ancrage de la barre d'outils, que l'utilisateur peut déplacer par une action de glisser-déposer, sera réalisé autour dudit composant.

Toute la construction de l'interface utilisateur de QtEd est effectuée au sein du constructeur de la classe EdMainWindow, elle-même décrite dans le fichier qted.py du CD-Rom.

Appréhendons à présent la mise en place d'une barre de statut. Pour ce faire, la classe QMainWindow met à disposition du programmeur la méthode publique self.statusBar(). Cette dernière renvoie l'instance de la barre de statut liée à la fenêtre. Lors du premier appel à cette méthode, la barre n'existe pas encore et se voit donc créée. Une telle barre permet d'afficher des informations simples, sous forme de texte. L'auteur y parviendra en invoquant les méthodes intitulées message(). Voici un court exemple d'utilisation d'une barre de statut :

self.myStatusBar = self.statusBar()
self.myStatusBar.message("Bienvenue !")
self.myStatusBar.message("Au revoir !", 2000)
       
      
JextCopier dans Jext | Jext | Plugin Codegeek
La première invocation de la méthode message() impliqué l'apparition du message "Bienvenue !" dans la barre de statut. La seconde invocation réalise la même chose mais n'affiche le message spécifié que pour une durée déterminée, exprimée en milli-secondes (ici, deux secondes).


 Barre de menus

La création d'une barre de menus est en tout point similaire à la création d'une barre de statut. QMainWindow offre une méthode appelée menuBar() qui renvoie l'instance de la barre de menu courante et qui la crée si besoin est. Chaque menu d'une barre de menu correspond à un menu contextuel (ou "popup menu"). Pour ajouter un nouveau menu dans une telle barre, le développeur doit se référer à la méthode insertItem() dont le premier paramètre définit le nom du menu et le second désigne le menu contextuel caractéristique du menu.

self.myMenuBar = self.menuBar()
self.myMenuBar.insertItem("&Fichier", fileMenu)
       
      
JextCopier dans Jext | Jext | Plugin Codegeek
Dans cet exemple, nous ajoutons le menu contextuel fileMenu à la barre. Un tel menu correspond en QT à une instance de la classe QPopupMenu. Celle-ci garantit l'ajout d'éléments et de sous-menus par l'entremise de ses différentes méthodes insertItem(). Lors de l'ajout un élément, nous devons lier cet événement à un slot (réceptacle). Le listing suivant présente les deux manières de le faire :

fileMenu = QPopupMenu(self)
fileMenu.insertItem('&Save',  self.save, Qt.CTRL + Qt.Key_S)
fileMenu.insertItem('&Close', self, SLOT('close()'), Qt.CTRL + Qt.Key_W)
       
      
JextCopier dans Jext
Dans le premier cas, le programmeur désigne simplement la méthode Python à exécuter lors d'une action sur l'élément. La seconde possibilité consiste à préciser l'objet récepteur (ici self) puis le slot appartenant au récepteur (ici la méthode close()). Le dernier paramètre employé au cours de ces deux appels sert à définir le raccourci clavier de l'élément de menu. Un raccourci clavier doit se voir défini par au moins une touche de modification (Control, Alt ou Majuscule) et une touche "normale". Ainsi, Qt.CTRL + Qt.ALT + Qt.Key_S correspond au raccourci clavier "Ctrl+Alt+S".


 Barre d'outils

La réalisation d'une barre d'outils se révèle toute aussi simple que la création d'une barre de menus ou de statut. Toutefois, la classe QMainWindow ne propose pas de méthode de création automatique pour une telle barre. PyQT désigne les barres d'outils à l'aide de la classe QToolBar. Une fois une barre d'outils créée, nous pouvons l'ajouter à notre fenêtre principale grâce à la méthode addToolBar() de la classe QMainWindow.

Durant la création d'une barre d'outils, le programmeur peut décider des emplacements capables de recevoir la barre. Cela signifie que si l'utilisateur a le droit de déplacer la barre d'outils dans l'interface, vous pouvez sans aucun problème restreindre les déplacements en interdisant par exemple les positions droite et gauche. Voici un exemple de code positionnant une barre d'outils à en bas de la fenêtre et n'autorisant son déplacement qu'en haut (le code appartient à une classe dérivant de QMainWindow) :

toolBar = QToolBar(self)
self.addToolBar(toolBar, self.Bottom, 0)
self.setDockEnabled(toolBar, self.Left, 0)
self.setDockEnabled(toolBar, self.Right, 0)
       
      
JextCopier dans Jext | Jext | Plugin Codegeek
Le troisième argument de la méthode addToolBar() indique si la barre d'outils doit commencer sur une nouvelle ligne. Ceci permet l'empilement des barres d'outils. Une barre d'outils ne propose aucune méthode particulière pour l'ajout de composants. En effet, il suffit d'utiliser la barre d'outils comme parent d'un composant pour provoquer l'ajout de ce dernier. De cette manière, une barre d'outils peut accueillir n'importe quel type de composant : bouton, liste déroulante. Néanmoins, le composant le plus courant se veut le QToolButton.

self.fileOpen = QToolButton(QPixmap(fileopen), 'Open File', \
'Opens a new file', self.open, toolBar, 'Open file')
       
      
JextCopier dans Jext
Le premier paramètre doit correspondre soit à une instance de QPixmap soit à une instance de QIconSet. Un QPixmap représente une image. La méthode la plus simple pour créer une telle image consiste à donner en paramètre du constructeur un tableau représentant le pixmap (format XPM).Bien entendu les pixmaps peuvent se voir chargés depuis des fichiers externes, référez-vous pour cela à la documentation de la classe QPixmap.


 L'application

Le reste de l'application n'offre que peu d'intérêt puisqu'il s'agit simplement de lire et d'écrire des fichiers. Un point particulier doit cependant être éclairci. Notre application contient une liste globale nommée windowsList, déclarée juste après les pixmaps. Cette liste revêt une importance capitale pour l'ouverture simultanée de plusieurs fenêtres de notre application. La méthode newFile() de EdMainWindow contient le code suivant :

ed = EdMainWindow()
ed.show()
windowsList.append(ed)
       
      
JextCopier dans Jext | Jext | Plugin Codegeek
La dernière ligne est quelque peu intrigante. Si nous enlevons cette ligne, un phénomène curieux apparaît : l'ouverture des nouvelles fenêtres ne marche plus ! L'explication est heureusement simple : lorsque l'interpréteur Python sort de la méthode newFile(), un ménage est fait parmi les différentes variables créées dans cette même méthode et l'instance ed est détruite. En ajoutant l'instance à une liste globale, Python ne la détruit pas et notre fenêtre apparaît correctement.


 Téléchargements

Nous vous conseillons de télécharger l'exemple complet.



par Romain Guy
romain.guy@jext.org
http://www.jext.org
Dernière mise à jour : 14/10/2006


Précédent  
  Python  
  Suivant

 
#ProgX©2005 Mathieu GINOD - Romain GUY - Erik LOUISE