Hay un conjunto general de métodos que se pueden usar para dibujar en el área de dibujo. Estos métodos de dibujo funcionan en cualquier gtk.gdk.Drawable (Dibujable), que es una gtk.gdk.Window (Ventana) o un gtk.gdk.Pixmap (Mapa de Píxeles). Los métodos de dibujo son:
drawable.draw_point(gc, x, y) # dibuja_punto |
gc es el Contexto Gráfico que se usará para hacer el dibujo.
x e y son las coordenadas del punto.
drawable.draw_line(gc, x1, y1, x2, y2) # dibuja linea |
gc es el Contexto Gráfico.
x1 e y1 especifican el punto de inicio de la linea. x2 e y2 especifican el punto final de la linea.
drawable.draw_rectangle(gc, filled, x, y, width, height) # dibuja rectángulo |
gc es el Contexto Gráfico.
filled es un valor booleano que indica si el rectángulo debe ser rellenado con el color de primer plano (valor TRUE) o no (valor FALSE).
x e y son las coordenadas de la esquina superior izquierda del rectángulo.
width y height son el ancho y el alto del rectángulo.
drawable.draw_arc(gc, filled, x, y, width, height, angle1, angle2) # dibuja arco |
gc es el Contexto Gráfico.
filled es un valor booleano que indica si el arco debe ser rellenado con el color de primer plano (valor TRUE) o no (valor FALSE).
x e y son las coordenadas de la esquina superior izquierda del rectángulo que bordea al arco. width y height son el ancho y el alto del rectángulo que bordea al arco.
angle1 es el ángulo inicial del arco, relativo a la posición de las 3 en punto del reloj, en el sentido contrario de las agujas del reloj, en sesenta y cuatroavos de grado.
angle2 es el ángulo final del arco, relativo a angle1, en sesenta y cuatroavos de grado en el sentido de las agujas del reloj.
drawable.draw_polygon(gc, filled, points) # dibuja polígono |
gc es el Contexto Gráfico.
filled es un valor booleano que especifica si el polígono debe ser rellenado con el color de primer plano o(valor TRUE) o no (valor FALSE).
points es una lista de los puntos que se van a dibujar como un polígono conectado, escrita como una lista de tuplas con las coordenadas, como por ejemplo: [ (0,0), (2,5), (3,7), (4,11) ].
drawable.draw_string(font, gc, x, y, string) # dibuja cadena drawable.draw_text(font, gc, x, y, string) # dibuja texto |
font es la gtk.gdk.Font (fuente) que se usará para pintar la cadena.
gc es el Contexto Gráfico.
x e y son las coordenadas del punto donde se empezará a dibujar la cadena, es decir, la línea base izquierda.
string es la cadena de caracteres a dibujar.
Ambos métodos draw_string() y draw_text() están obsoletos - en su lugar se debe usar un pango.Layout con el método draw_layout() .
drawable.draw_layout(gc, x, y, layout) # dibuja disposición |
gc es el Contexto Gráfico.
x e y son las coordenadas del punto desde el que se empieza a dibujar la disposición.
layout es el pango.Layout que se va a dibujar.
drawable.draw_drawable(gc, src, xsrc, ysrc, xdest, ydest, width, height) # dibuja dibujable |
gc es el Contexto Gráfico.
src es el dibujable de orígen.
xsrc e ysrc son las coordenadas de la esquina superior izquierda del rectángulo en el dibujable de orígen.
xdest e ydest son las coordenadas de la esquina superior izquierda en el área de dibujo.
width y height son el ancho y el alto del área del dibujable de origen que será copiada al dibujable (drawable). Si width o height es -1 entonces se usará el ancho o el alto total del dibujable.
drawable.draw_image(gc, image, xsrc, ysrc, xdest, ydest, width, height) # dibuja imagen |
gc es el Contexto Gráfico.
image es la imagen de origen.
xsrc e ysrc son las coordenadas de la esquina superior izquierda del rectángulo en el dibujable origen.
xdest e ydest son las coordenadas de la esquina superior izquierda del rectángulo en el área de dibujo.
width y height son el ancho y el alto del área del dibujable origen que se copiará en el dibujable (drawable) destino. Si width o height es -1 entonces se usará el ancho o el alto total de la imagen.
drawable.draw_points(gc, points) # dibuja puntos |
gc es el Contexto Gráfico.
points es una lista o tupla de pares de coordenadas en tuplas, por ejemplo [ (0,0), (2,5), (3,7), (4,11) ], que representa la lista de los puntos que se deben dibujar.
drawable.draw_segments(gc, segs) # dibuja segmentos |
gc es el Contexto Gráfico.
segs es una lista o tupla de tuplas que representan las coordenadas de los puntos iniciales y finales de los segmentos que se quiere dibujar, tal como: [ (0,0, 1,5), (2,5, 1,7), (3,7, 1,11), (4,11, 1,13) ] .
drawable.draw_lines(gc, points) # dibuja lineas |
gc es el Contexto Gráfico.
points es una lista o tupla de pares de coordenadas en tuplas, como por ejemplo [ (0,0), (2,5), (3,7), (4,11) ], que representa la lista de de los puntos que se van a conectar con líneas.
drawable.draw_rgb_image(gc, x, y, width, height, dith, rgb_buf, rowstride) # dibuja imagen rgb drawable.draw_rgb_32_image(gc, x, y, width, height, dith, buf, rowstride) # dibuja imagen rgb 32 drawable.draw_gray_image(gc, x, y, width, height, dith, buf, rowstride) # dibuja imagen en escala de grises |
gc es el Contexto Gráfico.
x e y son las coordenadas de la esquina superior izquierda del rectángulo que bordea la imagen.
width y height son el ancho y el alto del rectángulo que bordea la imagen.
dith es el uno de los métodos de mezclado que se explican a continuación:
Para el método draw_rgb_image() , rgb_buf es el conjunto de los datos de la imagen RGB codificado en una cadena como una secuencia de tripletes de píxeles RGB de 8 bits. Para el método draw_rgb_32_image() , buf es el conjunto de los datos de la imagen RGB codificado en una cadena como una secuencia de tripletes de píxeles RGB de 8 bits con relleno de 8 bits (4 caracteres por cada píxel RGB). Para el método draw_gray_image() , buf es el conjunto de datos de la imagen codificado en una cadena como píxeles de 8 bits.
rowstride es el número de caracteres desde el principio de una fila hasta el principio de la siguiente en la imagen. rowstride normalmente tiene un valor por defecto de 3 * ancho (width) en el método draw_rgb_image() ; 4 * ancho (width)para el método draw_rgb_32_image(); y el ancho (width) para el método draw_gray_image() . Si rowstride es 0 entonces la linea se repetirá un número de veces igual al alto.
Los modos de mezclado (dither) son:
RGB_DITHER_NONE # Nunca se hace mezclado RGB_DITHER_NORMAL # Se hace mezclado cuando se usen 8 bits por píxel (o menos) sólamente. RGB_DITHER_MAX # Se hace mezclado cuando se usen 16 bits por píxel o menos. |
El programa de ejemplo drawingarea.py muestra el uso de la mayoría de los métodos de un área de dibujo (DrawingArea). También inserta el área de dibujo (DrawingArea) en el interior de una ventana con barras de desplazamiento (ScrolledWindow) y añade los controles de desplazamiento horizontal y vertical (Ruler). La figura Figura 12.1, “Ejemplo de Área de Dibujo” muestra la ventana resultante:
El código fuente de drawingarea.py está abajo y usa el mapa de píxeles gtk.xpm :
1 #!/usr/bin/env python
2
3 # example drawingarea.py
4
5 import pygtk
6 pygtk.require('2.0')
7 import gtk
8 import operator
9 import time
10 import string
11
12 class DrawingAreaExample:
13 def __init__(self):
14 window = gtk.Window(gtk.WINDOW_TOPLEVEL)
15 window.set_title("Ejemplo de Área de Dibujo")
16 window.connect("destroy", lambda w: gtk.main_quit())
17 self.area = gtk.DrawingArea()
18 self.area.set_size_request(400, 300)
19 self.pangolayout = self.area.create_pango_layout("")
20 self.sw = gtk.ScrolledWindow()
21 self.sw.add_with_viewport(self.area)
22 self.table = gtk.Table(2,2)
23 self.hruler = gtk.HRuler()
24 self.vruler = gtk.VRuler()
25 self.hruler.set_range(0, 400, 0, 400)
26 self.vruler.set_range(0, 300, 0, 300)
27 self.table.attach(self.hruler, 1, 2, 0, 1, yoptions=0)
28 self.table.attach(self.vruler, 0, 1, 1, 2, xoptions=0)
29 self.table.attach(self.sw, 1, 2, 1, 2)
30 window.add(self.table)
31 self.area.set_events(gtk.gdk.POINTER_MOTION_MASK |
32 gtk.gdk.POINTER_MOTION_HINT_MASK )
33 self.area.connect("expose-event", self.area_expose_cb)
34 def motion_notify(ruler, event):
35 return ruler.emit("motion_notify_event", event)
36 self.area.connect_object("motion_notify_event", motion_notify,
37 self.hruler)
38 self.area.connect_object("motion_notify_event", motion_notify,
39 self.vruler)
40 self.hadj = self.sw.get_hadjustment()
41 self.vadj = self.sw.get_vadjustment()
42 def val_cb(adj, ruler, horiz):
43 if horiz:
44 span = self.sw.get_allocation()[3]
45 else:
46 span = self.sw.get_allocation()[2]
47 l,u,p,m = ruler.get_range()
48 v = adj.value
49 ruler.set_range(v, v+span, p, m)
50 while gtk.events_pending():
51 gtk.main_iteration()
52 self.hadj.connect('value-changed', val_cb, self.hruler, True)
53 self.vadj.connect('value-changed', val_cb, self.vruler, False)
54 def size_allocate_cb(wid, allocation):
55 x, y, w, h = allocation
56 l,u,p,m = self.hruler.get_range()
57 m = max(m, w)
58 self.hruler.set_range(l, l+w, p, m)
59 l,u,p,m = self.vruler.get_range()
60 m = max(m, h)
61 self.vruler.set_range(l, l+h, p, m)
62 self.sw.connect('size-allocate', size_allocate_cb)
63 self.area.show()
64 self.hruler.show()
65 self.vruler.show()
66 self.sw.show()
67 self.table.show()
68 window.show()
69
70 def area_expose_cb(self, area, event):
71 self.style = self.area.get_style()
72 self.gc = self.style.fg_gc[gtk.STATE_NORMAL]
73 self.draw_point(10,10)
74 self.draw_points(110, 10)
75 self.draw_line(210, 10)
76 self.draw_lines(310, 10)
77 self.draw_segments(10, 100)
78 self.draw_rectangles(110, 100)
79 self.draw_arcs(210, 100)
80 self.draw_pixmap(310, 100)
81 self.draw_polygon(10, 200)
82 self.draw_rgb_image(110, 200)
83 return gtk.TRUE
84
85 def draw_point(self, x, y):
86 self.area.window.draw_point(self.gc, x+30, y+30)
87 self.pangolayout.set_text("Punto")
88 self.area.window.draw_layout(self.gc, x+5, y+50, self.pangolayout)
89 return
90
91 def draw_points(self, x, y):
92 points = [(x+10,y+10), (x+10,y), (x+40,y+30),
93 (x+30,y+10), (x+50,y+10)]
94 self.area.window.draw_points(self.gc, points)
95 self.pangolayout.set_text("Puntos")
96 self.area.window.draw_layout(self.gc, x+5, y+50, self.pangolayout)
97 return
98
99 def draw_line(self, x, y):
100 self.area.window.draw_line(self.gc, x+10, y+10, x+20, y+30)
101 self.pangolayout.set_text("Línea")
102 self.area.window.draw_layout(self.gc, x+5, y+50, self.pangolayout)
103 return
104
105 def draw_lines(self, x, y):
106 points = [(x+10,y+10), (x+10,y), (x+40,y+30),
107 (x+30,y+10), (x+50,y+10)]
108 self.area.window.draw_lines(self.gc, points)
109 self.pangolayout.set_text("Líneas")
110 self.area.window.draw_layout(self.gc, x+5, y+50, self.pangolayout)
111 return
112
113 def draw_segments(self, x, y):
114 segments = ((x+20,y+10, x+20,y+70), (x+60,y+10, x+60,y+70),
115 (x+10,y+30 , x+70,y+30), (x+10, y+50 , x+70, y+50))
116 self.area.window.draw_segments(self.gc, segments)
117 self.pangolayout.set_text("Segmentos")
118 self.area.window.draw_layout(self.gc, x+5, y+80, self.pangolayout)
119 return
120
121 def draw_rectangles(self, x, y):
122 self.area.window.draw_rectangle(self.gc, gtk.FALSE, x, y, 80, 70)
123 self.area.window.draw_rectangle(self.gc, gtk.TRUE, x+10, y+10, 20, 20)
124 self.area.window.draw_rectangle(self.gc, gtk.TRUE, x+50, y+10, 20, 20)
125 self.area.window.draw_rectangle(self.gc, gtk.TRUE, x+20, y+50, 40, 10)
126 self.pangolayout.set_text("Rectángulos")
127 self.area.window.draw_layout(self.gc, x+5, y+80, self.pangolayout)
128 return
129
130 def draw_arcs(self, x, y):
131 self.area.window.draw_arc(self.gc, gtk.FALSE, x+10, y, 70, 70,
132 0, 360*64)
133 self.area.window.draw_arc(self.gc, gtk.TRUE, x+30, y+20, 10, 10,
134 0, 360*64)
135 self.area.window.draw_arc(self.gc, gtk.TRUE, x+50, y+20, 10, 10,
136 0, 360*64)
137 self.area.window.draw_arc(self.gc, gtk.TRUE, x+30, y+10, 30, 50,
138 210*64, 120*64)
139 self.pangolayout.set_text("Arcos")
140 self.area.window.draw_layout(self.gc, x+5, y+80, self.pangolayout)
141 return
142
143 def draw_pixmap(self, x, y):
144 pixmap, mask = gtk.gdk.pixmap_create_from_xpm(
145 self.area.window, self.style.bg[gtk.STATE_NORMAL], "gtk.xpm")
146
147 self.area.window.draw_drawable(self.gc, pixmap, 0, 0, x+15, y+25,
148 -1, -1)
149 self.pangolayout.set_text("Mapa de Píxeles")
150 self.area.window.draw_layout(self.gc, x+5, y+80, self.pangolayout)
151 return
152
153 def draw_polygon(self, x, y):
154 points = [(x+10,y+60), (x+10,y+20), (x+40,y+70),
155 (x+30,y+30), (x+50,y+40)]
156 self.area.window.draw_polygon(self.gc, gtk.TRUE, points)
157 self.pangolayout.set_text("Polígono")
158 self.area.window.draw_layout(self.gc, x+5, y+80, self.pangolayout)
159 return
160
161 def draw_rgb_image(self, x, y):
162 b = 80*3*80*['\0']
163 for i in range(80):
164 for j in range(80):
165 b[3*80*i+3*j] = chr(255-3*i)
166 b[3*80*i+3*j+1] = chr(255-3*abs(i-j))
167 b[3*80*i+3*j+2] = chr(255-3*j)
168 buff = string.join(b, '')
169 self.area.window.draw_rgb_image(self.gc, x, y, 80, 80,
170 gtk.gdk.RGB_DITHER_NONE, buff, 80*3)
171 self.pangolayout.set_text("Imagen RGB")
172 self.area.window.draw_layout(self.gc, x+5, y+80, self.pangolayout)
173 return
174
175 def main():
176 gtk.main()
177 return 0
178
179 if __name__ == "__main__":
180 DrawingAreaExample()
181 main()
|