P
'
t
i
t
e
C
h
a
t
t
e
 
spacer~ IT'S NOT BOGUS, IT'S AN IBM STANDARD Articles | Connexion
 
~wxPython 2/2

Précédent  
  Python  
  Suivant
 Présentation

L'article de ce mois-ci se propose de continuer plus avant la découverte de la librairie graphique wxWindows. L'objectif va consister en l'écriture d'un petit visualiseur d'images bitmap (format BMP).
 Sommaire


 Introdution

La réalisation d'un visualiseur d'images ne demande que très peu de composants graphiques. Notre application doit permettre d'ouvrir tout fichier bitmap portant l'extension .bmp et de l'afficher dans une fenêtre. Dans le cas très probable où la taille en pixels de l'image excède celle de la fenêtre de l'application, nous devrons offrir un moyen simple de modifier la vue de l'image.


 Teuteus

Avant de nous pencher sur les aspect les plus techniques de l'application, nous allons explorer divers petits détails graphiques des applications wxWindows. Nous avons appris le mois dernier à réaliser une barre de statut employée pour afficher de courts messages d'aide lors du survol de certains éléments graphiques. Le code source du visualiseur fait appel à une variante :

self.CreateStatusBar(2)
self.SetStatusText("BMP Viewer", 0)
       
      
JextCopier dans Jext | Jext | Plugin Codegeek
Une barre de statut peut se voir scindée en plusieurs compartiments. Dans des traitements de texte, ces compartiments indiquent souvent la position au sein du document, le statut de certaines fonctions (insertion, remplacement), et ainsi de suite. Notre application utilise deux compartiments : l'un pour afficher des messages d'aide, et l'autre pour afficher le nom du fichier en cours de visualisation. Le changement du contenu d'un compartiment est précisé par le second paramètre de la méthode SetStatusText() reflétant l'indice du compartiment cible.

Le second petit artifice graphique destiné à égayer un petit peu l'ensemble concerne le choix d'un icône pour la fenêtre principale. Pour ce faire, une seule ligne de code suffit :

self.SetIcon(wxIcon("mainIcon.ico", wxBITMAP_TYPE_ICO));
       
      
JextCopier dans Jext
Un programme wxWindows possède l'opportunité d'employer différents types d'icônes : des fichiers .ico, des fichiers XPM, des fichiers GIF... La documentation de wxWindows répertorie l'ensemble des valeurs possibles pour le second argument du constructeur de la classe wxIcon.


 Défilé

Parmi la multitude de composants graphiques accessibles au sein de la bibliothèque wxWindows, se trouve un composant très simple servant à afficher une image. Ce composant s'intitule wxStaticBitmap et nécessite l'usage d'une autre classe nommée wxBitmap. La classe wxBitmap sert à représenter une image en mémoire. Ainsi, pour chager en mémoire un fichier bitmap quelconque, le programmeur n'a besoin que d'exécuter l'instruction suivante :

image = wxBitmap("chick.bmp")
       
      
JextCopier dans Jext | Jext | Plugin Codegeek
Le second paramètre, optionnel, permet de sélectionner le type de l'image à ouvrir (BMP, PNG...). L'affichage d'un bitmap dans une interface wxWindows est possible en insérant l'image ainsi créée dans un conteneur, un paneau, capable d'afficher des images :

self.bitmap = wxStaticBitmap(self, -1, wxBitmap("gfxsign.bmp"))
       
      
JextCopier dans Jext
L'instance de wxStaticBitmap que nous générons se voit référencée comme membre de la classe afin de garantir le changement ultérieur de l'image présentée. La ligne de code précédente affiche l'image "gfxsign.bmp" au coeur de la fenêtre de l'application. Malheureusement, si les dimensions de l'image sont trop importantes, certaines portions de l'image resteront invisibles à l'utilisateur. Pour remédier à cet inconvénient nous devons placer le panneau de l'image dans un composant possédant des propriétés de défilement. En résumé, nous aurons un wxBitmap placé dans un wxStaticBitmap lui même appartenant à un panneau défilant inséré dans une fenêtre.

Les panneaux défilants de wxWindows correspondent à des instances de la classe wxScrolledWindow. Cette définit un panneau possdédant des barres de défilement horizontale et verticale. En spécifiant la capacité d'incrément et le nombre d'unité de chaque barre, le programmeur désigne explicitement la taille maximale acceptée par le panneau. Le panneau emploie deux tailles : celle de la vue physique (c'est à dire la surface réellement affichée), et celle de la vue virtuelle (soit la capacité en pixel du conteneur). En faisant défiler les barres, la vue physique est déplacée au dessus de la vue virtuelle, découvrant un nouveau morceau d'image jusqu'alors caché. La vue virtuelle est fixe tandis que la vue physique se veut dynamique, puisque modifiée à chaque redimensionnement de la fenêtre.

Les deux lignes de code source suivantes génèrent un panneau défilant accueillant un afficheur d'images :

self.scrollPane = wxScrolledWindow(self , -1, wxDefaultPosition, \
  wxDefaultSize, wxHSCROLL | wxVSCROLL);
self.bitmap = wxStaticBitmap(self.scrollPane, -1, wxBitmap("gfxsign.bmp"));
       
      
JextCopier dans Jext
Notez que le parent du wxStaticBitmap n'est plus self, mais scrollPane. La dernière valeur de paramètre donnée dans le constructeur de wxScrolledWindow définit la présence ou non des barres de défilement verticale et horizontale. Ici, les deux seront visibles par défaut. Pour les deux objets, le second paramètre, qui correspond rappelons-le à l'identificateur d'événements, prend la valeur -1. Ceci intime l'ordre à wxWindows de générer un identificateur lui-même.


 Ouverture d'une image

Le processus d'ouverture d'une nouvelle image dans le visualiseur a lieu dans la méthode OnOpen() de la classe ViewerFrame. Les deux lignes nécessaires à la création du menu d'ouverture et à la gestion de ses éventuels événements sont les suivantes :

menuFile.Append(ID_MENU_OPEN, "&Open...\tCtrl-O", "Open a bitmap picture")
EVT_MENU(self, ID_MENU_OPEN, self.OnOpen)
       
      
JextCopier dans Jext | Jext | Plugin Codegeek
A l'instar de l'exemple du mois dernier, la méthode OnOpen() fait appel à la classe wxFileDialog() pour afficher une boîte d'ouverture de fichier possédant un filtre restrictif sur un seul type de fichiers. La boîte utilisée dans notre exemple ne peut ouvrir qu'un seul fichier à la fois. Néanmoins, nous pouvons imaginer une amélioration de notre application qui permettrait l'ouverture de plusieurs images à la fois. Dans ce cas, une nouvelle fenêtre serait créée pour chaque image. A l'ouverture d'une image donc, l'application doit charger le nouveau fichier en mémoire au sein d'un objet wxBitmap. Ces objets ont la particularité de renseigner, entre autres, sur la largeur et la hauteur des images. Ceci nous est nécessaire pour paramétrer les barres de défilement. Nous avons sélectionné un incrément arbitraire de cinq pixels. Cela signifie que pour chaque clic sur les barres de défilement, la vue se déplacera de cinq pixels. La méthode SetScrollbars() des objets wxScrolledWindow définit successivement l'incrément horzontal, l'incrément vertical et le nombre d'unités horizontales puis verticales. Pour un incrément de cinq pixels sur chacun des axes, nous devons assigner un nombre d'unités égal à [dimension de l'image sur cet axe] / 5 afin de faire correspondre exactement la vue virtuelle avec la taille réelle de l'image.

Il ne vous reste plus qu'à les différents exemples de cet article.

def OnOpen(self, event):
  dialog = wxFileDialog(self, "Choose a bitmap", "", "", \
  "BMP files (*.bmp)|*.bmp", wxOPEN)
  if dialog.ShowModal() == wxID_OK:
    self.SetStatusText(dialog.GetFilename(), 1);
    bmp = wxBitmap(dialog.GetFilename(), wxBITMAP_TYPE_BMP)
    self.scrollPane.SetScrollbars(5, 5, bmp.GetWidth() / 5, bmp.GetHeight() / 5)
    self.bitmap.SetBitmap(bmp)
       
      
JextCopier dans Jext


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