12.2. Métodos de Dibujo

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 a 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 o no.

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 o no.

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 seseinta y cuatroavos de grado.

angle2 es el ángulo final del arco, relativo a angle1, en seseinta 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 no.

points es una lista de pares de coordenadas en tuplas, por ejemplo [ (0,0), (2,5), (3,7), (4,11) ], de los puntos que se van a dibujar como un polígono conectado.

  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 de base izquierda.

string es la cadena de caracteres a dibujar.

Nota

Ambos métodos draw_string() y draw_text() están obsoletos - en su lugar usa 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 orígen que será copiada en el drawable. Si width o height es -1 entonces el ancho o el alto completo del dibujable se usará.

  drawable.draw_image(gc, image, xsrc, ysrc, xdest, ydest, width, height) # dibuja imágen

gc es el Contexto Gráfico.

image es la imágen orígen.

xsrc e ysrc son las coordenadas de la esquina superior izquierda del rectángulo en el dibujable orígen.

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 orígen que se copiará en el dibujable destino. Si width o height es -1 entonces se usará el ancho o el alto completo de la imágen.

  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) ], de los puntos a dibujar.

  drawable.draw_segments(gc, segs) # dibuja segmentos

gc es el Contexto Gráfico.

segs es una lista o tupla de pares de coordenadas iniciales y finales en tuplas, por ejemplo [ (0,0, 1,5), (2,5, 1,7), (3,7, 1,11), (4,11, 1,13) ], de los segmentos de lineas a dibujar.

  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, por ejemplo [ (0,0), (2,5), (3,7), (4,11) ], de los puntos a conectar con lineas.

  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 imágen.

width y height son el ancho y el alto del rectángulo que bordea la imágen.

dith es el método de mezclado y se explica a continuación:

Para el método draw_rgb_image() , rgb_buf es el conjunto de los datos de la imágen RGB codificados en una cadena como una secuencia de triples de píxeles RGB de 8 bits. Para el método draw_rgb_32_image() , buf es el conjunto de los datos de la imágen RGB codificados en una cadena como una secuencia de triples 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 imágen codificados 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 fila en la imágen. rowstride normalmente es 3 * ancho en el método draw_rgb_image() ; 4 * ancho para el método draw_rgb_32_image(); y el ancho 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 tipos de mezclado son:

  RGB_DITHER_NONE    # Nunca usar mezclado

  RGB_DITHER_NORMAL  # Usar mezclado cuando se usen 8 bits por píxel (o menos)
sólamente.

  RGB_DITHER_MAX     # Usar 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 DrawingArea . La figura Figura 12.1. Ejemplo de Área de Dibujo muestra la ventana resultante:

Figura 12.1. Ejemplo de Área de Dibujo

Ejemplo de Área de Dibujo

El código fuente drawingarea.py está abajo y usa el pixmap gtk.xpm :

    1   #!/usr/bin/env python
    2   
    3   # example drawingarea.py
    4   
    5	import gtk
    6	import operator
    7	import time
    8	import string
    9	
   10	class DrawingAreaExample:
   11	    def __init__(self):
   12	        window = gtk.Window(gtk.WINDOW_TOPLEVEL)
   13	        window.set_title("Drawing Area Example")
   14	        window.connect("destroy", gtk.mainquit)
   15	        self.area = gtk.DrawingArea()
   16	        self.area.set_size_request(400, 300)
   17	        self.pangolayout = self.area.create_pango_layout("")
   18	        window.add(self.area)
   19	        self.area.connect("expose-event", self.area_expose_cb)
   20	        self.area.show()
   21	        window.show()
   22	
   23	    def area_expose_cb(self, area, event):
   24	        self.style = self.area.get_style()
   25	        self.gc = self.style.fg_gc[gtk.STATE_NORMAL]
   26	        self.draw_point(10,10)
   27	        self.draw_points(110, 10)
   28	        self.draw_line(210, 10)
   29	        self.draw_lines(310, 10)
   30	        self.draw_segments(10, 100)
   31	        self.draw_rectangles(110, 100)
   32	        self.draw_arcs(210, 100)
   33	        self.draw_pixmap(310, 100)
   34	        self.draw_polygon(10, 200)
   35	        self.draw_rgb_image(110, 200)
   36	        return gtk.TRUE
   37	
   38	    def draw_point(self, x, y):
   39	        self.area.window.draw_point(self.gc, x+300, y+300)
   40	        self.pangolayout.set_text("Point", -1)
   41	        self.area.window.draw_layout(self.gc, x+5, y+50, self.pangolayout)
   42	        return
   43	
   44	    def draw_points(self, x, y):
   45	        points = [(x+10,y+10), (x+10,y), (x+40,y+30),
   46	                  (x+30,y+10), (x+50,y+10)]
   47	        self.area.window.draw_points(self.gc, points)
   48	        self.pangolayout.set_text("Points", -1)
   49	        self.area.window.draw_layout(self.gc, x+5, y+50, self.pangolayout)
   50	        return
   51	
   52	    def draw_line(self, x, y):
   53	        self.area.window.draw_line(self.gc, x+10, y+10, x+20, y+30)
   54	        self.pangolayout.set_text("Line", -1)
   55	        self.area.window.draw_layout(self.gc, x+5, y+50, self.pangolayout)
   56	        return
   57	
   58	    def draw_lines(self, x, y):
   59	        points = [(x+10,y+10), (x+10,y), (x+40,y+30),
   60	                  (x+30,y+10), (x+50,y+10)]
   61	        self.area.window.draw_lines(self.gc, points)
   62	        self.pangolayout.set_text("Lines", -1)
   63	        self.area.window.draw_layout(self.gc, x+5, y+50, self.pangolayout)
   64	        return
   65	
   66	    def draw_segments(self, x, y):
   67	        segments = ((x+20,y+10, x+20,y+70), (x+60,y+10, x+60,y+70),
   68	            (x+10,y+30 , x+70,y+30), (x+10, y+50 , x+70, y+50))
   69	        self.area.window.draw_segments(self.gc, segments)
   70	        self.pangolayout.set_text("Segments", -1)
   71	        self.area.window.draw_layout(self.gc, x+5, y+80, self.pangolayout)
   72	        return
   73	
   74	    def draw_rectangles(self, x, y):
   75	        self.area.window.draw_rectangle(self.gc, gtk.FALSE, x, y, 80, 70)
   76	        self.area.window.draw_rectangle(self.gc, gtk.TRUE, x+10, y+10, 20, 20)
   77	        self.area.window.draw_rectangle(self.gc, gtk.TRUE, x+50, y+10, 20, 20)
   78	        self.area.window.draw_rectangle(self.gc, gtk.TRUE, x+20, y+50, 40, 10)
   79	        self.pangolayout.set_text("Rectangles", -1)
   80	        self.area.window.draw_layout(self.gc, x+5, y+80, self.pangolayout)
   81	        return
   82	
   83	    def draw_arcs(self, x, y):
   84	        self.area.window.draw_arc(self.gc, gtk.FALSE, x+10, y, 70, 70,
   85	                                  0, 360*64)
   86	        self.area.window.draw_arc(self.gc, gtk.TRUE, x+30, y+20, 10, 10,
   87	                                  0, 360*64)
   88	        self.area.window.draw_arc(self.gc, gtk.TRUE, x+50, y+20, 10, 10,
   89	                                  0, 360*64)
   90	        self.area.window.draw_arc(self.gc, gtk.TRUE, x+30, y+10, 30, 50,
   91	                                  210*64, 120*64)
   92	        self.pangolayout.set_text("Arcs", -1)
   93	        self.area.window.draw_layout(self.gc, x+5, y+80, self.pangolayout)
   94	        return
   95	
   96	    def draw_pixmap(self, x, y):
   97	        pixmap, mask = gtk.gdk.pixmap_create_from_xpm(
   98	            self.area.window, self.style.bg[gtk.STATE_NORMAL], "gtk.xpm")
   99	
  100	        self.area.window.draw_drawable(self.gc, pixmap, 0, 0, x+15, y+25,
  101	                                       -1, -1)
  102	        self.pangolayout.set_text("Pixmap", -1)
  103	        self.area.window.draw_layout(self.gc, x+5, y+80, self.pangolayout)
  104	        return
  105	
  106	    def draw_polygon(self, x, y):
  107	        points = [(x+10,y+60), (x+10,y+20), (x+40,y+70),
  108	                  (x+30,y+30), (x+50,y+40)]
  109	        self.area.window.draw_polygon(self.gc, gtk.TRUE, points)
  110	        self.pangolayout.set_text("Polygon", -1)
  111	        self.area.window.draw_layout(self.gc, x+5, y+80, self.pangolayout)
  112	        return
  113	
  114	    def draw_rgb_image(self, x, y):
  115	        b = 80*3*80*['\0']
  116	        for i in range(80):
  117	            for j in range(80):
  118	                b[3*80*i+3*j] = chr(255-3*i)
  119	                b[3*80*i+3*j+1] = chr(255-3*abs(i-j))
  120	                b[3*80*i+3*j+2] = chr(255-3*j)
  121	        buff = string.join(b, '')
  122	        self.area.window.draw_rgb_image(self.gc, x, y, 80, 80,
  123	                                 gtk.gdk.RGB_DITHER_NONE, buff, 80*3)
  124	        self.pangolayout.set_text("RGB Image", -1)
  125	        self.area.window.draw_layout(self.gc, x+5, y+80, self.pangolayout)
  126	        return
  127	
  128	def main():
  129	    gtk.main()
  130	    return 0
  131	
  132	if __name__ == "__main__":
  133	    DrawingAreaExample()
  134	    main()