Las Images (Imágenes) son estructuras de datos que contienen dibujos. Estos dibujos se pueden usar en varios sitios.
Las Images (Imágenes) se pueden crear a partir de Pixbufs, Pixmaps, archivos que contengan información de imagen (por ejemplo. XPM, PNG, JPEG, TIFF, etc.), e incluso ficheros de animación.
Las Images (Imágenes) se crean usando la función:
image = gtk.Image() |
Después se carga la imagen usando alguno de los siguientes métodos:
image.set_from_pixbuf(pixbuf) image.set_from_pixmap(pixmap, mask) image.set_from_image(image) image.set_from_file(filename) image.set_from_stock(stock_id, size) image.set_from_icon_set(icon_set, size) image.set_from_animation(animation) |
Donde pixbuf es un GdkPixbuf; pixmap y mask son gtk.gdk.Pixmaps; image es una gtk.gdk.Image; stock_id es el nombre de un gtk.StockItem; icon_set es un gtk.IconSet; y, animation es una gtk.gdk.PixbufAnimation. el argumento size (tamaño) es uno de:
ICON_SIZE_MENU ICON_SIZE_SMALL_TOOLBAR ICON_SIZE_LARGE_TOOLBAR ICON_SIZE_BUTTON ICON_SIZE_DND ICON_SIZE_DIALOG |
La forma más fácil de crear una imagen es usar el método set_from_file() que automáticamente determina el tipo de imagen y la carga.
El programa images.py muestra cómo cargar varios tipos de imagen (goalie.gif, apple-red.png, chaos.jpg, important.tif, soccerball.gif) en imágenes que se colocan dentro de botones:
El código fuente es:
1 #!/usr/bin/env python
2
3 # ejemplo images.py
4
5 import pygtk
6 pygtk.require('2.0')
7 import gtk
8
9 class ImagesExample:
10 # cuando se invoca (con la señal delete_event), finaliza la aplicación
11 def close_application(self, widget, event, data=None):
12 gtk.main_quit()
13 return gtk.FALSE
14
15 # se invoca cuando el botón es pulsado. Simplemente imprime un mensaje.
16 def button_clicked(self, widget, data=None):
17 print "button %s clicked" % data
18
19 def __init__(self):
20 # crea la ventana principal y conecta la señal delete_event signal para finalizar
21 # la aplicación
22 window = gtk.Window(gtk.WINDOW_TOPLEVEL)
23 window.connect("delete_event", self.close_application)
24 window.set_border_width(10)
25 window.show()
26
27 # una caja horizontal que contenga los botones
28 hbox = gtk.HBox()
29 hbox.show()
30 window.add(hbox)
31
32 pixbufanim = gtk.gdk.PixbufAnimation("goalie.gif")
33 image = gtk.Image()
34 image.set_from_animation(pixbufanim)
35 image.show()
36 # un botón que contenga el control de imagen
37 button = gtk.Button()
38 button.add(image)
39 button.show()
40 hbox.pack_start(button)
41 button.connect("clicked", self.button_clicked, "1")
42
43 # crear varias imágenes con datos de archivos y cargarlos
44 # en botones
45 image = gtk.Image()
46 image.set_from_file("apple-red.png")
47 image.show()
48 # un botón que cotenga el control de imagen
49 button = gtk.Button()
50 button.add(image)
51 button.show()
52 hbox.pack_start(button)
53 button.connect("clicked", self.button_clicked, "2")
54
55 image = gtk.Image()
56 image.set_from_file("chaos.jpg")
57 image.show()
58 # un botón que cotenga el control de imagen
59 button = gtk.Button()
60 button.add(image)
61 button.show()
62 hbox.pack_start(button)
63 button.connect("clicked", self.button_clicked, "3")
64
65 image = gtk.Image()
66 image.set_from_file("important.tif")
67 image.show()
68 # un botón que cotenga el control de imagen
69 button = gtk.Button()
70 button.add(image)
71 button.show()
72 hbox.pack_start(button)
73 button.connect("clicked", self.button_clicked, "4")
74
75 image = gtk.Image()
76 image.set_from_file("soccerball.gif")
77 image.show()
78 # un botón que cotenga el control de imagen
79 button = gtk.Button()
80 button.add(image)
81 button.show()
82 hbox.pack_start(button)
83 button.connect("clicked", self.button_clicked, "5")
84
85
86 def main():
87 gtk.main()
88 return 0
89
90 if __name__ == "__main__":
91 ImagesExample()
92 main()
|
Los Pixmaps son estructuras de datos que contienen dibujos. Estos dibujos se pueden usar en varios sitios, pero lo más común es usarlos como iconos en un escritorio X, o como cursores.
Un pixmap con sólo 2 colores se llama bitmap, y hay unas cuantas rutinas adicionales para trabajar con este caso especial.
Para entender los pixmaps, es de ayuda entender cómo funciona el sistema X Window. En X, las aplicaciones no necesitan ejecutarse en el mismo ordenador que interactua con el usuario. En cambio, estas aplicaciones, llamadas "clientes", se comunican con un programa que muestra los gráficos y maneja el teclado y el ratón. Este programa que interactua directamente con el usuario se llama un "servidor de visualización" o "servidor X". Ya que la comunicación puede tener lugar sobre una red, es importante mantener alguna información en el servidor X. Los Pixmaps, por ejemplo, se almacenan en la memoria del servidor X. Esto significa que, una vez que los valores de un pixmap se establecen, no hay que seguir transmitiendolos por la red; en lugar de eso, se envía un comando para "mostrar el pixmap número XYZ aqui." Incluso si no se está usando X con GTK simultáneamente, usando construcciones como Pixmaps hará que los programas funcionen de forma aceptable en X.
Para usar pixmaps en PyGTK, primero debemos construir un gtk.gdk.Pixmap usando las funciones de gtk.gdk en PyGTK. Los Pixmaps se pueden crear a partir de datos en memoria, o a partir de datos leídos desde un fichero. Veamos cada una de las llamadas usadas para crear un pixmap.
pixmap = gtk.gdk.pixmap_create_from_data(window, data, width, height, depth, fg, bg) |
Esta rutina se usa para crear un pixmap con la profundidad de color dada por el argumento depth a partir de los datos data en memoria. Si depth es -1 su valor se deduce de la de la ventana window. Cada pixel usa un número de bits de datos para representar el color que es igual a la profundidad de color. El width(ancho) y el height (alto) son en pixeles. El argumento window (ventana) debe referirse a una gtk.gdk.Window realizada, ya que los recursos de un pixmap sólo tienen sentido en el contexto de la pantalla donde se va a visualizar. fg y bg son los colores de frente y fondo del pixmap.
Se pueden crear pixmaps desde ficheros XPM usando:
pixmap, mask = gtk.gdk.pixmap_create_from_xpm(window, transparent_color, filename) |
El formato XPM es una representación legible de pixmap para el Sistema de Ventanas X. Es usado ampliamente y hay muchas utilidades disponibles para crear ficheros de imágenes en este formato. En la función pixmap_create_from_xpm() el primer argumento es del tipo gtk.gdk.Window . (La mayoría de los controles GTK tienen una gtk.gdk.Window subyacente que se puede obtener usando el atributo window (ventana) del control.) El fichero se especifica con filename y debe contener una imagen en formato XPM el cual se carga en la estructura del pixmap. La mask (máscara) es un bitmap que especifica qué bits del pixmap son opacos; se crea con la función. Todos los demás pixeles se colorean con el color especificado por transparent_color. Un ejemplo del uso de esta función se recoge a continuación.
Los Pixmaps también puede crearse a partir de datos en memoria usando la función:
pixmap, mask = gtk.gdk.pixmap_create_from_xpm_d(window, transparent_color, data) |
Imagenes pequeñas se pueden incorporar a un programa como datos en el formato XPM usando la función anterior. Un pixmap se crea usando estos datos, en lugar de leerlo de un fichero. Un ejemplo de este tipo de datos es:
xpm_data = [ "16 16 3 1", " c None", ". c #000000000000", "X c #FFFFFFFFFFFF", " ", " ...... ", " .XXX.X. ", " .XXX.XX. ", " .XXX.XXX. ", " .XXX..... ", " .XXXXXXX. ", " .XXXXXXX. ", " .XXXXXXX. ", " .XXXXXXX. ", " .XXXXXXX. ", " .XXXXXXX. ", " .XXXXXXX. ", " ......... ", " ", " " ] |
La última forma para crear un pixmap en blanco disponible para operaciones de dibujo es:
pixmap = gtk.gdk.Pixmap(window, width, height, depth=-1) |
window es o una gtk.gdk.Window o None. Si window es una gtk.gdk.Window entonces depth puede ser -1 para indicar que la profundidad de color se obtiene de la ventana. Si window es None entonces depth debe especificarse.
El programa pixmap.py es un ejemplo del uso de un pixmap en un botón. La figura Figura 9.6, “Ejemplo de Pixmap en un Botón” muestra el resultado:
El código fuente es:
1 #!/usr/bin/env python
2
3 # ejemplo pixmap.py
4
5 import pygtk
6 pygtk.require('2.0')
7 import gtk
8
9 # XPM data of Open-File icon
10 xpm_data = [
11 "16 16 3 1",
12 " c None",
13 ". c #000000000000",
14 "X c #FFFFFFFFFFFF",
15 " ",
16 " ...... ",
17 " .XXX.X. ",
18 " .XXX.XX. ",
19 " .XXX.XXX. ",
20 " .XXX..... ",
21 " .XXXXXXX. ",
22 " .XXXXXXX. ",
23 " .XXXXXXX. ",
24 " .XXXXXXX. ",
25 " .XXXXXXX. ",
26 " .XXXXXXX. ",
27 " .XXXXXXX. ",
28 " ......... ",
29 " ",
30 " "
31 ]
32
33 class PixmapExample:
34 # cuando se invoca (con la señal delete_event), finaliza la aplicación.
35 def close_application(self, widget, event, data=None):
36 gtk.main_quit()
37 return gtk.FALSE
38
39 # se invoca al pulsar el botón. Simplemente imprime un mensaje
40 def button_clicked(self, widget, data=None):
41 print "button clicked"
42
43 def __init__(self):
44 # crea la ventana principal y conecta la señal delete_event para finalizar
45 # la aplicación
46 window = gtk.Window(gtk.WINDOW_TOPLEVEL)
47 window.connect("delete_event", self.close_application)
48 window.set_border_width(10)
49 window.show()
50
51 # ahora el pixmap desde datos XPM
52 pixmap, mask = gtk.gdk.pixmap_create_from_xpm_d(window.window,
53 None,
54 xpm_data)
55
56 # un control de imagen que contenga el pixmap
57 image = gtk.Image()
58 image.set_from_pixmap(pixmap, mask)
59 image.show()
60
61 # un botón que contenga el control de imagen
62 button = gtk.Button()
63 button.add(image)
64 window.add(button)
65 button.show()
66
67 button.connect("clicked", self.button_clicked)
68
69 def main():
70 gtk.main()
71 return 0
72
73 if __name__ == "__main__":
74 PixmapExample()
75 main()
|
Una desventaja de usar pixmaps es que que el objeto mostrado siempre es rectangular, independientemente de la imagen. Nos gustaría crear escritorios y aplicaciones con iconos que tengan formas más naturales. Por ejemplo, para la interfaz de un juego, nos gustaría tener botones redondos para pulsar. La forma de hacer esto es usar ventanas con forma.
Una ventana con forma es simplemente un pixmap en el que los pixeles de fondo son transparentes. De esta forma, cuando la imagen de fondo se colorea, no la sobreescribimos con un borde rectangular y que no encaja, de nuestro icono. El programa de ejemplo wheelbarrow.p muestra una imagen completa en el escritorio. La figura Figura 9.7, “Ejemplo de Ventana con Forma” muestra la imagen sobre una ventana de terminal:
The source code for wheelbarrow.py is:
1 #!/usr/bin/env python
2
3 # ejemplo wheelbarrow.py
4
5 import pygtk
6 pygtk.require('2.0')
7 import gtk
8
9 # XPM
10 WheelbarrowFull_xpm = [
11 "48 48 64 1",
12 " c None",
13 ". c #DF7DCF3CC71B",
14 "X c #965875D669A6",
15 "o c #71C671C671C6",
16 "O c #A699A289A699",
17 "+ c #965892489658",
18 "@ c #8E38410330C2",
19 "# c #D75C7DF769A6",
20 "$ c #F7DECF3CC71B",
21 "% c #96588A288E38",
22 "& c #A69992489E79",
23 "* c #8E3886178E38",
24 "= c #104008200820",
25 "- c #596510401040",
26 "; c #C71B30C230C2",
27 ": c #C71B9A699658",
28 "> c #618561856185",
29 ", c #20811C712081",
30 "< c #104000000000",
31 "1 c #861720812081",
32 "2 c #DF7D4D344103",
33 "3 c #79E769A671C6",
34 "4 c #861782078617",
35 "5 c #41033CF34103",
36 "6 c #000000000000",
37 "7 c #49241C711040",
38 "8 c #492445144924",
39 "9 c #082008200820",
40 "0 c #69A618611861",
41 "q c #B6DA71C65144",
42 "w c #410330C238E3",
43 "e c #CF3CBAEAB6DA",
44 "r c #71C6451430C2",
45 "t c #EFBEDB6CD75C",
46 "y c #28A208200820",
47 "u c #186110401040",
48 "i c #596528A21861",
49 "p c #71C661855965",
50 "a c #A69996589658",
51 "s c #30C228A230C2",
52 "d c #BEFBA289AEBA",
53 "f c #596545145144",
54 "g c #30C230C230C2",
55 "h c #8E3882078617",
56 "j c #208118612081",
57 "k c #38E30C300820",
58 "l c #30C2208128A2",
59 "z c #38E328A238E3",
60 "x c #514438E34924",
61 "c c #618555555965",
62 "v c #30C2208130C2",
63 "b c #38E328A230C2",
64 "n c #28A228A228A2",
65 "m c #41032CB228A2",
66 "M c #104010401040",
67 "N c #492438E34103",
68 "B c #28A2208128A2",
69 "V c #A699596538E3",
70 "C c #30C21C711040",
71 "Z c #30C218611040",
72 "A c #965865955965",
73 "S c #618534D32081",
74 "D c #38E31C711040",
75 "F c #082000000820",
76 " ",
77 " .XoO ",
78 " +@#$%o& ",
79 " *=-;#::o+ ",
80 " >,<12#:34 ",
81 " 45671#:X3 ",
82 " +89<02qwo ",
83 "e* >,67;ro ",
84 "ty> 459@>+&& ",
85 "$2u+ ><ipas8* ",
86 "%$;=* *3:.Xa.dfg> ",
87 "Oh$;ya *3d.a8j,Xe.d3g8+ ",
88 " Oh$;ka *3d$a8lz,,xxc:.e3g54 ",
89 " Oh$;kO *pd$%svbzz,sxxxxfX..&wn> ",
90 " Oh$@mO *3dthwlsslszjzxxxxxxx3:td8M4 ",
91 " Oh$@g& *3d$XNlvvvlllm,mNwxxxxxxxfa.:,B* ",
92 " Oh$@,Od.czlllllzlmmqV@V#V@fxxxxxxxf:%j5& ",
93 " Oh$1hd5lllslllCCZrV#r#:#2AxxxxxxxxxcdwM* ",
94 " OXq6c.%8vvvllZZiqqApA:mq:Xxcpcxxxxxfdc9* ",
95 " 2r<6gde3bllZZrVi7S@SV77A::qApxxxxxxfdcM ",
96 " :,q-6MN.dfmZZrrSS:#riirDSAX@Af5xxxxxfevo",
97 " +A26jguXtAZZZC7iDiCCrVVii7Cmmmxxxxxx%3g",
98 " *#16jszN..3DZZZZrCVSA2rZrV7Dmmwxxxx&en",
99 " p2yFvzssXe:fCZZCiiD7iiZDiDSSZwwxx8e*>",
100 " OA1<jzxwwc:$d%NDZZZZCCCZCCZZCmxxfd.B ",
101 " 3206Bwxxszx%et.eaAp77m77mmmf3&eeeg* ",
102 " @26MvzxNzvlbwfpdettttttttttt.c,n& ",
103 " *;16=lsNwwNwgsvslbwwvccc3pcfu<o ",
104 " p;<69BvwwsszslllbBlllllllu<5+ ",
105 " OS0y6FBlvvvzvzss,u=Blllj=54 ",
106 " c1-699Blvlllllu7k96MMMg4 ",
107 " *10y8n6FjvllllB<166668 ",
108 " S-kg+>666<M<996-y6n<8* ",
109 " p71=4 m69996kD8Z-66698&& ",
110 " &i0ycm6n4 ogk17,0<6666g ",
111 " N-k-<> >=01-kuu666> ",
112 " ,6ky& &46-10ul,66, ",
113 " Ou0<> o66y<ulw<66& ",
114 " *kk5 >66By7=xu664 ",
115 " <<M4 466lj<Mxu66o ",
116 " *>> +66uv,zN666* ",
117 " 566,xxj669 ",
118 " 4666FF666> ",
119 " >966666M ",
120 " oM6668+ ",
121 " *4 ",
122 " ",
123 " "
124 ]
125
126 class WheelbarrowExample:
127 # Cuando se invoca (con la señal delete_event), finaliza la aplicación
128 def close_application(self, widget, event, data=None):
129 gtk.main_quit()
130 return gtk.FALSE
131
132 def __init__(self):
133 # Crea la ventana principal y conecta la señal delete_event para finalizar
134 # la aplicación. Obsérvese que la ventana principal no tendrá título
135 # ya que vamos a hacer una ventana emergente (popup).
136 window = gtk.Window(gtk.WINDOW_POPUP)
137 window.connect("delete_event", self.close_application)
138 window.set_events(window.get_events() | gtk.gdk.BUTTON_PRESS_MASK)
139 window.connect("button_press_event", self.close_application)
140 window.show()
141
142 # ahora para el pixmap y el control de imagen
143 pixmap, mask = gtk.gdk.pixmap_create_from_xpm_d(
144 window.window, None, WheelbarrowFull_xpm)
145 image = gtk.Image()
146 image.set_from_pixmap(pixmap, mask)
147 image.show()
148
149 # Para mostrar la imagen usamos un control fijo para situarla
150 fixed = gtk.Fixed()
151 fixed.set_size_request(200, 200)
152 fixed.put(image, 0, 0)
153 window.add(fixed)
154 fixed.show()
155
156 # Esto enmascara todo salvo la imagen misma
157 window.shape_combine_mask(mask, 0, 0)
158
159 # mostramos la ventana
160 window.set_position(gtk.WIN_POS_CENTER_ALWAYS)
161 window.show()
162
163 def main():
164 gtk.main()
165 return 0
166
167 if __name__ == "__main__":
168 WheelbarrowExample()
169 main()
|
Para hacer la imagen sensible, conectamos la señal "button_press_event" para que el programa finalice. Las lineas 138-139 hacen el dibujo sensible a una pulsación de un botón del ratón y lo conectan al método close_application() .