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() .