IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Apprendre à utiliser le module Python PyGTK 2.0


précédentsommairesuivant

XII. Chapitre 12. La zone de dessin (Drawing Area)

La zone de dessin DrawingArea adapte une gtk.gdk.Window, laquelle est une sous-classe de gtk.gdk.Drawable (de même que gtk.gdk.Pixmap). En effet, la DrawingArea fournit un simple "canevas", la gtk.gdk.Window adaptée sur laquelle on peut dessiner en utilisant les méthodes de la classe gtk.gdk.Drawable.

On crée une DrawingArea en utilisant le constructeur :

 
Sélectionnez
  zone_dessin = gtk.DrawingArea()

Une DrawingArea est créée au départ avec une taille de (0, 0) donc pour rendre visible la zone_dessin, il faut préciser sa largeur et sa hauteur avec des valeurs supérieures à zéro en utilisant la méthode suivante :

 
Sélectionnez
  zone_dessin.set_size_request(largeur, hauteur)

Pour dessiner sur une DrawingArea, il faut récupérer la gtk.gdk.Window en utilisant l'attribut window de la zone de dessin de cette manière :

 
Sélectionnez
  dessinable = drawing_area.window

Ensuite, il est possible de dessiner sur le dessinable en utilisant la méthode gtk.gdk.Drawable décrite dans la Section 12.2, « Les méthodes pour dessiner »Les méthodes pour dessiner.

Pour posséder une gtk.gdk.Window associée pouvant être utilisée pour le dessin, le widget DrawingArea doit être "réalisé" (on a utilisé la méthode realize()).

XII-A. Le contexte graphique

Il existe un grand nombre de méthodes pour dessiner sur la gtk.gdk.Window d'une zone de dessin. Toutes ces méthodes exigent un contexte graphique (gtk.gdk.GC) pour encapsuler l'information nécessaire au dessin sous forme d'attributs. Un gtk.gdk.GC dispose des attributs suivants :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
background            # fond
cap_style             # style de fin de ligne
clip_mask             # masque de découpe
clip_x_origin         # origine x de la découpe
clip_y_origin         # origine y de la découpe
fill                  # remplissage
font                  # police
foreground            # couleur de premier plan
function              # fonction
graphics_exposures    # exposition graphique
join_style            # style de jointure de lignes
line_style            # style de ligne
line_width            # largeur de ligne
stipple               # style de pointillé
sub_window            # sous-fenêtre
tile                  # mosaïque
ts_x_origin           # origine x
ts_y_origin           # origine y

background définit la gtk.gdk.Color utilisée comme couleur de fond.

foreground définit la gtk.gdk.Color utilisée comme couleur de premier plan.

Une gtk.gdk.Color est une couleur qui peut être allouée ou non allouée. Une couleur non allouée peut être créée avec le constructeur :

 
Sélectionnez
  couleur = gtk.gdk.Color(red=0, green=0, blue=0, pixel=0)

où les paramètres red, green et blue sont des entiers compris entre 0 et 65535. Le paramètre pixel n'est pas souvent défini, car il est réécrit lorsque la couleur est allouée.

Une gtk.gdk.Color non allouée peut aussi être créée par la fonction :

 
Sélectionnez
  couleur = gtk.gdk.color_parse(spec)

spec est une chaine de spécification de couleur qui peut être :

  • un nom de couleur (par exemple "red", "orange", "navajo white" tels qu'ils sont définis dans le fichier X Window rgb.txt), oo ;
  • une chaine hexadécimale débutant par '#' et contenant trois groupes des chiffres hexadécimaux de même longueur ((1, 2, 3 ou 4 chiffres). Par exemple, "#F0A", "#FF00AA", "#FFF000AAA" et "#FFFF0000AAAA" qui représentent tous la même couleur.

Pour créer une gtk.gdk.Color représentant une couleur allouée, on utilise la méthode alloc_color() de gtk.gdk.Colormap qui possède trois variantes :

 
Sélectionnez
1.
2.
3.
4.
5.
  couleur = colormap.alloc_color(color, writeable=FALSE, best_match=TRUE)

  couleur = colormap.alloc_color(spec, writeable=FALSE, best_match=TRUE)

  couleur = colormap.alloc_color(red, green, blue, writeable=FALSE, best_match=TRUE)

Le paramètre couleur est un gtk.gdk.Color non alloué, spec est une chaine de spécification de couleur comme on l'a vu précédemment dans la fonction gtk.gdk.color_parse(). Les paramètres red, green et blue sont des valeurs entières de couleur décrites dans la fonction constructeur gtk.gdk.Color(). On peut aussi indiquer si la couleur allouée peut être modifiable (c.-à-d. , peut être modifiée plus tard, mais ne peut pas être partagée) ou si une meilleure approximation avec des couleurs existantes peut se faire lorsque la couleur exacte n'est pas disponible.

Par exemple :

 
Sélectionnez
1.
2.
3.
4.
5.
  navajowhite = colormap.alloc('navajo white')

  cyan = colormap.alloc(0, 65535, 65535)

  red = colormap.alloc_color('#FF0000', True, True)

On peut connaître la palette de couleurs associée à un widget par la méthode :

 
Sélectionnez
  palette = widget.get_colormap()

cap_style précise le style de fin de ligne utilisé pour une ligne qui se termine sans rejoindre une autre. Les différents styles disponibles sont :

 
Sélectionnez
CAP_NOT_LAST

Dessine la même fin de ligne que CAP_BUTT pour des lignes de largeur non nulle. Pour des lignes de largeur nulle, le point final de la ligne n'est pas dessiné.

 
Sélectionnez
CAP_BUTT

La fin de ligne est carrée et étendue jusqu'aux coordonnées du point final.

 
Sélectionnez
CAP_ROUND

La fin de ligne est arrondie (demi-cercle d'un diamètre égal à l'épaisseur de la ligne) et centrée sur le point final.

 
Sélectionnez
CAP_PROJECTING

La fin de ligne est carrée et étendue de la moitié de l'épaisseur de la ligne après le point final.

clip_mask définit un gtk.gdk.Pixmap utilisé pour découper le dessin de la zone de dessin drawing_area.

clip_x_origin et clip_y_origin précise pour le découpage, l'origine en x et y par rapport au coin supérieur gauche de la zone de dessin.

fill précise le style de remplissage utilisé dans le dessin. Les styles disponibles sont :

 
Sélectionnez
SOLID

Dessine avec la couleur de premier plan.

 
Sélectionnez
TILED

Dessine avec un dessin en mosaïque.

 
Sélectionnez
STIPPLED

Dessine avec un patron de pointillé. Les pixels définis qui correspondent aux bits dans le patron seront dessinés dans la couleur de premier plan ; les pixels non définis qui correspondent aux bits dans le patron seront laissés intacts.

 
Sélectionnez
OPAQUE_STIPPLED

Dessine avec un patron de pointillé. Les pixels correspondants aux bits. Les pixels définis qui correspondent aux bits dans le patron seront dessinés dans la couleur de premier plan ; les pixels non définis qui correspondent aux bits dans le patron seront dessinés dans la couleur d'arrière-plan (de fond).

font est un gtk.gdk.Font qui est la police utilisée par défaut pour le texte du dessin.

L'utilisation de l'attribut font est abandonnée.

function précise comment les valeurs de bit pour les pixels source sont combinées avec les valeurs de bit pour les pixels de destination pour produire les bits de pixels résultat. Les seize valeurs suivantes correspondent aux 16 différentes possibilités d'une table de vérité 2x2, mais deux ou trois de ces valeurs seulement sont réellement utiles. Pour les images en couleur, seul COPY, XOR et INVERT sont généralement utiles alors que pour les bitmaps AND et OR sont aussi utilisés. Voici les valeurs possibles de function :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
  COPY           # copie
  INVERT         # inverser
  XOR            # OU exclusif
  CLEAR          # nettoyer
  AND            # ET
  AND_REVERSE    
  AND_INVERT     # ET inversé
  NOOP           # nul
  OR             # OU
  EQUIV          # équivalent
  OR_REVERSE     
  COPY_INVERT    # copie inversée
  OR_INVERT      # OU inversé
  NAND           # non ET
  SET            # afficher ?

graphics_exposures indique si l'affichage graphique est autorisé (TRUE) ou interdit (FALSE). Lorsque graphics_exposures vaut TRUE, l'échec de copie d'un pixel dans une action de dessin génère un événement expose. Si la copie réussit, un événement noexpose est généré.

join_style indique le style de croisement entre deux lignes. Les styles disponibles sont :

 
Sélectionnez
JOIN_MITER

Les côtés de chaque ligne sont prolongés pour se rencontrer en formant un angle.

 
Sélectionnez
JOIN_ROUND

Les côtés des deux lignes se rejoignent en formant un arrondi.

 
Sélectionnez
JOIN_BEVEL

Les côtés des deux lignes sont joints par un segment formant un angle égal avec chaque ligne.

line_style indique le style de traçage d'une ligne. Les possibilités sont :

 
Sélectionnez
LINE_SOLID

Les lignes sont tracées en continu.

 
Sélectionnez
LINE_ON_OFF_DASH

Les segments pairs sont dessinés, pas les segments impairs (ligne discontinue).

 
Sélectionnez
LINE_DOUBLE_DASH

Les segments pairs sont dessinés normalement. Les segments impairs sont dessinés dans la couleur de fond si le style de remplissage est SOLID, dans la couleur de fond avec le masque de pointillé si le style est STIPPLED.

line_width indique l'épaisseur de la ligne.

stipple indique le gtk.gdk.Pixmap utilisé pour un dessin en pointillé quand le paramètre fill vaut STIPPLED ou OPAQUE_STIPPLED.

sub_window indique le mode de dessin dans une gtk.gdk.Window qui possède des enfants gtk.gdk.Window. Les valeurs possibles pour sub_window sont :

 
Sélectionnez
CLIP_BY_CHILDREN

Dessine seulement dans la fenêtre elle-même, pas dans ses fenêtres enfants.

 
Sélectionnez
INCLUDE_INFERIORS

Dessine dans la fenêtre et dans ses fenêtres enfants.

tile indique le gtk.gdk.Pixmap utilisé pour dessiner en mosaïque lorsque le paramètre fill vaut TILED.

ts_x_origin et ts_y_origin indiquent l'origine de la mosaïque ou du pointillé (la position de départ du bitmap).

Un nouveau contexte graphique est créé par un appel à la méthode gtk.gdk.Drawable.new_gc() :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
contexte_graph = drawable.new_gc(foreground=None, background=None, font=None, 
                     function=-1, fill=-1, tile=None,
                     stipple=None, clip_mask=None, subwindow_mode=-1,
                     ts_x_origin=-1, ts_y_origin=-1, clip_x_origin=-1,
                     clip_y_origin=-1, graphics_exposures=-1,
                     line_width=-1, line_style=-1, cap_style=-1
                     join_style=-1)

Pour pouvoir créer un nouveau contexte graphique avec cette méthode, le drawable doit être :

  • une gtk.gdk.Window qui a été réalisée (créée), ou ;
  • un gtk.gdk.Pixmap associé à une gtk.gdk.Window réalisée.

Les différents attributs du contexte graphique possèdent des valeurs par défaut lorsqu'elles ne sont pas précisées dans la méthode new_gc(). Lorsque l'on souhaite définir des attributs du contexte graphique par la méthode new_gc(), il est plus facile d'utiliser les arguments par mot-clés de Python.

On peut aussi définir les attributs individuels d'un gtk.gdk.GC en assignant une valeur aux attributs de l'objet GC. Par exemple :

 
Sélectionnez
1.
2.
3.
4.
  gc.cap_style = CAP_BUTT
  gc.line_width = 10
  gc.fill = SOLD
  gc.foreground = macouleur

ou en utilisant les méthodes suivantes :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
  gc.set_foreground(color)
  gc.set_background(color)
  gc.set_function(function)
  gc.set_fill(fill)
  gc.set_tile(tile)
  gc.set_stipple(stipple)
  gc.set_ts_origin(x, y)
  gc.set_clip_origin(x, y)
  gc.set_clip_mask(mask)
  gc.set_clip_rectangle(rectangle)
  gc.set_subwindow(mode)
  gc.set_exposures(exposures)
  gc.set_line_attributes(line_width, line_style, cap_style, join_style)

Le patron de segments utilisé lorsque le paramètre de style de ligne line_style est LINE_ON_OFF_DASH ou LINE_DOUBLE_DASH peut être défini par la méthode suivante :

 
Sélectionnez
  gc.set_dashes(offset, dash_list)

où le paramètre offset est la position de la valeur du segment initial dans la dash_list et dash_list est une liste de tuples contenant le nombre de pixels à dessiner ou à sauter pour réaliser les segments. Les segments sont dessinés en démarrant avec le nombre de pixels indiqué à la position de décalage (offset) ; ensuite le nombre suivant est le nombre de pixels sautés ; le nombre suivant est le nombre de pixels dessinés, et ainsi de suite, parcourant tous les nombres de la dash_list en recommençant au début quand on arrive à la fin de la liste. Par exemple, si la dash_list se compose de (2, 4, 8, 16) avec un décalage (offset) de 1, les segments sont dessinés ainsi : dessin sur 4 pixels, saut de 8 pixels, dessin sur 16 pixels, saut de 2 pixels, dessin sur 4 pixels, etc.

On peut réaliser une copie d'un gtk.gdk.GC existant par la méthode :

 
Sélectionnez
  gc.copy(src_gc)

Les attributs du paramètre gc sont identiques à ceux du paramètre source src_gc.

XII-B. Les méthodes pour dessiner

Il existe un ensemble de méthodes pour dessiner sur le "canevas" d'une zone de dessin. Ces méthodes peuvent être utilisées pour n'importe quelle sous-classe de gtk.gdk.Drawable (soit un gtk.gdk.Window, soit un gtk.gdk.Pixmap). Les voici :

 
Sélectionnez
  drawable.draw_point(gc, x, y) # dessiner un point

gc est le contexte graphique utilisé pour le dessin.

x et y sont les coordonnées du point.

 
Sélectionnez
  drawable.draw_line(gc, x1, y1, x2, y2) # dessiner une ligne

gc est le contexte graphique.

x1 et y1 sont les coordonnées du point de départ, x2 et y2 les coordonnées du point d'arrivée.

 
Sélectionnez
  drawable.draw_rectangle(gc, filled, x, y, largeur, hauteur) # dessiner un rectangle

gc est le contexte graphique.

filled est un booléen indiquant si le rectangle doit être rempli avec la couleur de premier plan (TRUE) ou non (FALSE).

x et y sont les coordonnées du coin haut gauche du rectangle.

largeur et hauteur indiquent la largeur et la hauteur du rectangle :

 
Sélectionnez
  drawable.draw_arc(gc, filled, x, y, largeur, hauteur, angle1, angle2) # dessiner un arc de cercle

gc est le contexte graphique.

filled est un booléen indiquant si le rectangle doit être rempli avec la couleur de premier plan (TRUE) ou non (FALSE).

x et y sont les coordonnées du coin haut gauche du rectangle inscrit. largeur et hauteur indiquent la largeur et hauteur du rectangle inscrit.

angle1 est l'angle de départ de l'arc, en partant de la position 3 heures, dans le sens inverse des aiguilles d'une montre, par pas de 1/64 degré.

angle2 est la fin de l'angle de l'arc, relatif à angle1, par pas de 1/64 degré.

 
Sélectionnez
  drawable.draw_polygon(gc, filled, points) # dessiner un polygone

gc est le contexte graphique.

filled est un booléen indiquant si le rectangle doit être rempli avec la couleur de premier plan (TRUE) ou non (FALSE).

points est un tuple contenant une liste de paires de coordonnées, par exemple [ (0,0), (2,5), (3,7), (4,11) ], désignant les points devant être reliés pour dessiner un polygone.

 
Sélectionnez
1.
2.
3.
  drawable.draw_string(font, gc, x, y, string) # dessiner une chaine de caractères

  drawable.draw_text(font, gc, x, y, string) # dessiner un texte

font est le gtk.gdk.Font utilisé pour dessiner la chaine de caractères.

gc est le contexte graphique.

x et y sont les coordonnées du point où commence le dessin de la chaine, c'est-à-dire, la ligne de base de gauche.

string est la chaine de caractères à dessiner.

Les deux méthodes draw_string() et draw_text() sont démodées. Il faut plutôt utiliser un pango.Layout avec la méthode draw_layout().

 
Sélectionnez
  drawable.draw_layout(gc, x, y, layout) # dessiner un affichage

gc est le contexte graphique.

x et y sont les coordonnées du point où débute le dessin du layout.

layout est le pango.Layout qui va être dessiné.

 
Sélectionnez
  drawable.draw_drawable(gc, src, xsrc, ysrc, xdest, ydest, largeur, hauteur) # dessiner un dessinable

gc est le contexte graphique.

src est le dessinable d'origine.

xsrc et ysrc sont les coordonnées du rectangle supérieur gauche dans la source dessinable.

xdest et ydest sont les coordonnées du coin haut gauche de la zone de dessin.

largeur et hauteur sont la largeur et hauteur du dessinable d'origine à copier sur le dessinable. Si l'un de ces paramètres vaut -1, on utilise la largeur ou hauteur complète du dessinable.

 
Sélectionnez
  drawable.draw_image(gc, image, xsrc, ysrc, xdest, ydest, largeur, hauteur) # dessiner une image

gc est le contexte graphique.

image est l'image origine.

xsrc et ysrc sont les coordonnées du coin supérieur gauche du rectangle dans le dessinable source.

xdest et ydest sont les coordonnées du coin supérieur gauche dans la zone de dessin.

largeur et hauteur sont la largeur et hauteur de la zone dessinable origine qui doit être copiée sur le dessinable (drawable). Si l'un de ces paramètres vaut -1, on utilise la largeur ou la hauteur complète de l'image.

 
Sélectionnez
  drawable.draw_points(gc, points) # dessiner des points

gc est le contexte graphique.

points est une liste ou un tuple contenant les tuples de paires de coordonnées, par exemple [ (0,0), (2,5), (3,7), (4,11) ] désignant les points à dessiner.

 
Sélectionnez
  drawable.draw_segments(gc, segs) # dessiner des segments de ligne

gc est le contexte graphique.

segs est une liste ou un tuple des coordonnées des points de départ et de fin des segments à dessiner, contenues dans un tuple, par exemple [ (0,0, 1,5), (2,5, 1,7), (3,7, 1,11), (4,11, 1,13) ].

 
Sélectionnez
  drawable.draw_lines(gc, points) # dessiner une ligne brisée

gc est le contexte graphique.

points est une liste ou un tuple contenant les tuples de paires de coordonnées, par exemple [ (0,0), (2,5), (3,7), (4,11) ] désignant les points à relier par des lignes.

 
Sélectionnez
1.
2.
3.
4.
5.
  drawable.draw_rgb_image(gc, x, y, largeur, hauteur, dith, rgb_buf, rowstride)

  drawable.draw_rgb_32_image(gc, x, y, largeur, hauteur, dith, buf, rowstride)

  drawable.draw_gray_image(gc, x, y, largeur, hauteur, dith, buf, rowstride)

gc est le contexte graphique.

x et y sont les coordonnées du coin supérieur gauche du rectangle qui contient l'image.

largeur et hauteur sont la largeur et la hauteur du rectangle qui contient l'image.

dith est le mode de diffusion (tramage) décrit ci-dessous.

Pour la méthode draw_rgb_image(), le paramètre rgb_buf représente les données de l'image RGB, codifiées dans une chaine sous forme de séquence de triplets de pixels RGB de 8 bits. Pour la méthode draw_rgb_32_image(), buf représente les données de l'image RGB, codifiées dans une chaine sous forme de séquence de triplets de pixels RGB de 8 bits avec 8 bits de padding (4 caractères par pixel RGB). Pour la méthode draw_gray_image(), buf représente les données de l'image codifiées dans une chaine de pixels de 8 bits.

rowstride est le nombre de caractères depuis le début d'une rangée jusqu'au début de la rangée suivante de l'image. Normalement sa valeur par défaut est 3 * largeur pour la méthode draw_rgb_image(), 4 * largeur pour la méthode draw_rgb_32_image() et largeur pour la méthode draw_gray_image(). Si rowstride vaut 0, la ligne sera répétée hauteur fois.

Voici les différents modes de diffusion (dither) :

 
Sélectionnez
1.
2.
3.
4.
5.
  RGB_DITHER_NONE    # Ne pas utiliser de diffusion.

  RGB_DITHER_NORMAL  # Utiliser la diffusion si seulement 8 bits par pixels (ou moins).

  RGB_DITHER_MAX     # Utiliser la diffusion si 16 bits par pixels (ou moins).

Le programme exemple drawingarea.py illustre l'utilisation de la plupart des méthodes de la DrawingArea. Il place une zone de dessin (DrawingArea) dans une fenêtre défilante ScrolledWindow et ajoute des règles horizontales et verticales (Ruler). La Figure 12.1, « Exemple de Drawing Area » montre le programme après lancement :

Image non disponible
Figure 12.1. Exemple de Drawing Area

Le code source ci-dessous drawingarea.py ci-dessous utilise l'image pixmap gtk.xpm

 
Sélectionnez
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.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# exemple drawingarea.py

import pygtk
pygtk.require('2.0')
import gtk
import operator
import time
import string

class ExempleZoneDessin:
    def __init__(self):
        fenêtre = gtk.Window(gtk.WINDOW_TOPLEVEL)
        fenetre.set_title("Exemple de zone de dessin")
        fenetre.connect("destroy", lambda w: gtk.main_quit())
        self.zone_dessin = gtk.DrawingArea()
        self.zone_dessin.set_size_request(400, 300)
        self.stylepango = self.zone_dessin.create_pango_layout("")
        self.fenetre_defil = gtk.ScrolledWindow()
        self.fenetre_defil.add_with_viewport(self.zone_dessin)
        self.table = gtk.Table(2,2)
        self.reglehoriz = gtk.HRuler()
        self.reglevert = gtk.VRuler()
        self.reglehoriz.set_range(0, 400, 0, 400)
        self.reglevert.set_range(0, 300, 0, 300)
        self.table.attach(self.reglehoriz, 1, 2, 0, 1, yoptions=0)
        self.table.attach(self.reglevert, 0, 1, 1, 2, xoptions=0)
        self.table.attach(self.fenetre_defil, 1, 2, 1, 2)
        fenetre.add(self.table)
        self.zone_dessin.set_events(gtk.gdk.POINTER_MOTION_MASK |
                             gtk.gdk.POINTER_MOTION_HINT_MASK )
        self.zone_dessin.connect("expose-event", self.rappel_zone_dessin_expose)
        def a_bouge(ruler, event):
            return ruler.emit("motion_notify_event", event)
        self.zone_dessin.connect_object("motion_notify_event", a_bouge,
                                 self.reglehoriz)
        self.zone_dessin.connect_object("motion_notify_event", a_bouge,
                                 self.reglevert)
        self.ajuste_hor = self.fenetre_defil.get_hadjustment()
        self.ajuste_ver = self.fenetre_defil.get_vadjustment()
        def rappel_valeur(ajuste, regle, horiz):
            if horiz:
                span = self.fenetre_defil.get_allocation()[3]
            else:
                span = self.fenetre_defil.get_allocation()[2]
            l,u,p,m = regle.get_range()
            v = ajuste.value
            regle.set_range(v, v+span, p, m)
            while gtk.events_pending():
                gtk.main_iteration()
        self.ajuste_hor.connect('value-changed', rappel_valeur, self.reglehoriz, True)
        self.ajuste_ver.connect('value-changed', rappel_valeur, self.reglevert, False)
        def rappel_taille_fixee(wid, allocation):
            x, y, w, h = allocation
            l,u,p,m = self.reglehoriz.get_range()
            m = max(m, w)
            self.reglehoriz.set_range(l, l+w, p, m)
            l,u,p,m = self.reglevert.get_range()
            m = max(m, h)
            self.reglevert.set_range(l, l+h, p, m)
        self.fenetre_defil.connect('size-allocate', rappel_taille_fixee)
        self.zone_dessin.show()
        self.reglehoriz.show()
        self.reglevert.show()
        self.fenetre_defil.show()
        self.table.show()
        fenetre.show()

    def rappel_zone_dessin_expose(self, zone_dessin, event):
        self.style = self.zone_dessin.get_style()
        self.contexte_graph = self.style.fg_gc[gtk.STATE_NORMAL]
        self.trace_point(10,10)
        self.trace_points(110, 10)
        self.trace_ligne(210, 10)
        self.trace_lignes(310, 10)
        self.trace_segments(10, 100)
        self.trace_rectangles(110, 100)
        self.trace_arcs(210, 100)
        self.trace_pixmap(310, 100)
        self.trace_polygone(10, 200)
        self.trace_image_rgb(110, 200)
        return True

    def trace_point(self, x, y):
        self.zone_dessin.window.draw_point(self.contexte_graph, x+30, y+30)
        self.stylepango.set_text("Point")
        self.zone_dessin.window.draw_layout(self.contexte_graph, x+5, y+50, self.stylepango)
        return

    def trace_points(self, x, y):
        points = [(x+10,y+10), (x+10,y), (x+40,y+30),
                  (x+30,y+10), (x+50,y+10)]
        self.zone_dessin.window.draw_points(self.contexte_graph, points)
        self.stylepango.set_text("Points")
        self.zone_dessin.window.draw_layout(self.contexte_graph, x+5, y+50, self.stylepango)
        return

    def trace_ligne(self, x, y):
        self.zone_dessin.window.draw_line(self.contexte_graph, x+10, y+10, x+20, y+30)
        self.stylepango.set_text("Ligne")
        self.zone_dessin.window.draw_layout(self.contexte_graph, x+5, y+50, self.stylepango)
        return

    def trace_lignes(self, x, y):
        points = [(x+10,y+10), (x+10,y), (x+40,y+30),
                  (x+30,y+10), (x+50,y+10)]
        self.zone_dessin.window.draw_lines(self.contexte_graph, points)
        self.stylepango.set_text("Lignes")
        self.zone_dessin.window.draw_layout(self.contexte_graph, x+5, y+50, self.stylepango)
        return

    def trace_segments(self, x, y):
        segments = ((x+20,y+10, x+20,y+70), (x+60,y+10, x+60,y+70),
            (x+10,y+30 , x+70,y+30), (x+10, y+50 , x+70, y+50))
        self.zone_dessin.window.draw_segments(self.contexte_graph, segments)
        self.stylepango.set_text("Segments")
        self.zone_dessin.window.draw_layout(self.contexte_graph, x+5, y+80, self.stylepango)
        return

    def trace_rectangles(self, x, y):
        self.zone_dessin.window.draw_rectangle(self.contexte_graph, False, x, y, 80, 70)
        self.zone_dessin.window.draw_rectangle(self.contexte_graph, True, x+10, y+10, 20, 20)
        self.zone_dessin.window.draw_rectangle(self.contexte_graph, True, x+50, y+10, 20, 20)
        self.zone_dessin.window.draw_rectangle(self.contexte_graph, True, x+20, y+50, 40, 10)
        self.stylepango.set_text("Rectangles")
        self.zone_dessin.window.draw_layout(self.contexte_graph, x+5, y+80, self.stylepango)
        return

    def trace_arcs(self, x, y):
        self.zone_dessin.window.draw_arc(self.contexte_graph, False, x+10, y, 70, 70,
                                  0, 360*64)
        self.zone_dessin.window.draw_arc(self.contexte_graph, True, x+30, y+20, 10, 10,
                                  0, 360*64)
        self.zone_dessin.window.draw_arc(self.contexte_graph, True, x+50, y+20, 10, 10,
                                  0, 360*64)
        self.zone_dessin.window.draw_arc(self.contexte_graph, True, x+30, y+10, 30, 50,
                                  210*64, 120*64)
        self.stylepango.set_text("Arcs")
        self.zone_dessin.window.draw_layout(self.contexte_graph, x+30, y+80, self.stylepango)
        return

    def trace_pixmap(self, x, y):
        pixmap, mask = gtk.gdk.pixmap_create_from_xpm(
            self.zone_dessin.window, self.style.bg[gtk.STATE_NORMAL], "gtk.xpm")

        self.zone_dessin.window.draw_drawable(self.contexte_graph, pixmap, 0, 0, x+15, y+25,
                                       -1, -1)
        self.stylepango.set_text("Pixmap")
        self.zone_dessin.window.draw_layout(self.contexte_graph, x+5, y+80, self.stylepango)
        return

    def trace_polygone(self, x, y):
        points = [(x+10,y+60), (x+10,y+20), (x+40,y+70),
                  (x+30,y+30), (x+50,y+40)]
        self.zone_dessin.window.draw_polygon(self.contexte_graph, True, points)
        self.stylepango.set_text("Polygone")
        self.zone_dessin.window.draw_layout(self.contexte_graph, x+5, y+80, self.stylepango)
        return

    def trace_image_rgb(self, x, y):
        b = 80*3*80*['\0']
        for i in range(80):
            for j in range(80):
                b[3*80*i+3*j] = chr(255-3*i)
                b[3*80*i+3*j+1] = chr(255-3*abs(i-j))
                b[3*80*i+3*j+2] = chr(255-3*j)
        buff = string.join(b, '')
        self.zone_dessin.window.draw_rgb_image(self.contexte_graph, x, y, 80, 80,
                                 gtk.gdk.RGB_DITHER_NONE, buff, 80*3)
        self.stylepango.set_text("Image RGB")
        self.zone_dessin.window.draw_layout(self.contexte_graph, x+5, y+80, self.stylepango)
        return

def main():
    gtk.main()
    return 0

if __name__ == "__main__":
    ExempleZoneDessin()
    main()

précédentsommairesuivant

Copyright © 2005 John Finlay. Aucune reproduction, même partielle, ne peut être faite de ce site ni de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.