Pygtk2 Tut Es

download Pygtk2 Tut Es

of 360

Transcript of Pygtk2 Tut Es

  • Tutorial de PyGTK 2.0 versin 2.3

    John Finlay, Rafael Villar Burke, Lorenzo Gil Snchez,Iigo Serna, y Fernando San Martn Woerner

    7 de octubre de 2012

  • Tutorial de PyGTK 2.0 versin 2.3by John Finlay, Rafael Villar Burke, Lorenzo Gil Snchez, Iigo Serna, y Fernando San Martn Woerner

    II

  • ndice general

    1. Introduccin 11.1. Exploracin de PyGTK . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2

    2. Primeros Pasos 52.1. Hola Mundo en PyGTK . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72.2. Teora de Seales y Retrollamadas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92.3. Eventos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102.4. Hola Mundo Paso a Paso . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12

    3. Avanzando 153.1. Ms sobre manejadores de seales . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153.2. Un Hola Mundo Mejorado . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15

    4. Empaquetado de Controles 194.1. Teora de Cajas Empaquetadoras . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 194.2. Las Cajas en detalle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 194.3. Programa de Ejemplo de Empaquetado . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 214.4. Uso de Tablas para el Empaquetado . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 264.5. Ejemplo de Empaquetado con Tablas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27

    5. Perspectiva General de Controles 315.1. Jerarqua de Controles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 315.2. Controles sin Ventana . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34

    6. El Control de Botn 356.1. Botones Normales . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 356.2. Botones Biestado (Toggle Buttons) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 386.3. Botones de Activacin (Check Buttons) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 406.4. Botones de Exclusin Mtua (Radio Buttons) . . . . . . . . . . . . . . . . . . . . . . . . . . 42

    7. Ajustes 457.1. Creacin de un Ajuste . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 457.2. Utilizacin de Ajustes de la Forma Fcil . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 467.3. Interioridades de un Ajuste . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46

    8. Controles de Rango 498.1. Barras de Desplazamiento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 498.2. Controles de Escala . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49

    8.2.1. Creacin de un Control de Escala . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 498.2.2. Mtodos y Seales (bueno, al menos mtodos) . . . . . . . . . . . . . . . . . . . . . 50

    8.3. Mtodos Comunes de los Rangos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 508.3.1. Establecimiento de la Poltica de Actualizacin . . . . . . . . . . . . . . . . . . . . . 508.3.2. Obtencin y Cambio de Ajustes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51

    8.4. Atajos de Teclas y Ratn . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 518.5. Ejemplo de Control de Rango . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51

    9. Miscelnea de Controles 579.1. Etiquetas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 579.2. Flechas (Arrow) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 609.3. El Objeto Pistas (Tooltip) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 629.4. Barras de Progreso (ProgressBar) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 639.5. Dilogos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 679.6. Imgenes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68

    9.6.1. Pixmaps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 709.7. Reglas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76

    III

  • NDICE GENERAL

    9.8. Barras de Estado . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 799.9. Entradas de Texto (Entry) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 819.10. Botones Aumentar/Disminuir . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 849.11. Lista Desplegable (Combo) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 899.12. Calendario . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 909.13. Seleccin de Color . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 969.14. Selectores de Fichero . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1009.15. Dilogo de Seleccin de Fuentes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102

    10. Controles Contenedores 10510.1. La Caja de Eventos (EventBox) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10510.2. El control Alineador . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10610.3. Contenedor Fijo (Fixed) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10710.4. Contenedor de Disposicin (Layout) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10910.5. Marcos (Frame) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11110.6. Marcos Proporcionales (AspectFrame) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11310.7. Controles de Panel (HPaned y VPaned) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11510.8. Vistas (Viewport) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11810.9. Ventanas de Desplazamiento (ScrolledWindow) . . . . . . . . . . . . . . . . . . . . . . . . 11810.10.Cajas de Botones (ButtonBoxes) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12110.11.Barra de Herramientas (Toolbar) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12410.12.Fichas (Notebook) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12910.13.Elementos incrustables y puntos de conexin (Plugs y Sockets) . . . . . . . . . . . . . . . . 133

    10.13.1.Elementos incrustables (Plugs) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13310.13.2.Puntos de Conexin (Sockets) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134

    11. Control Men 13711.1. Creacin Manual de Mens . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13711.2. Ejemplo de Men Manual . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13911.3. Uso de la Factoria de Elementos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14111.4. Ejemplo de Factoria de Elementos - ItemFactory . . . . . . . . . . . . . . . . . . . . . . . . 141

    12. rea de Dibujo 14512.1. Contexto Grfico . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14512.2. Mtodos de Dibujo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149

    13. Control de Vista de Texto 15713.1. Perspectiva general de la Vista de Texto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15713.2. Vistas de Texto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15713.3. Buffers de Texto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163

    13.3.1. Informacin de estado de un Buffer de Texto . . . . . . . . . . . . . . . . . . . . . . 16313.3.2. Creacin de Iteradores de Texto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16413.3.3. Insercin, Obtencin y Eliminacin de Texto . . . . . . . . . . . . . . . . . . . . . . 16413.3.4. Marcas de Texto (TextMark) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16513.3.5. Creacin y Uso de Etiquetas de Texto . . . . . . . . . . . . . . . . . . . . . . . . . . 16613.3.6. Insercin de Imgenes y Controles . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167

    13.4. Iteradores de Texto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16813.4.1. Atributos de los Iteradores de Texto . . . . . . . . . . . . . . . . . . . . . . . . . . . 16813.4.2. Atributos de Texto de un Iterador de Texto . . . . . . . . . . . . . . . . . . . . . . . 16813.4.3. Copiar un Iterador de Texto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16913.4.4. Recuperar Texto y Objetos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16913.4.5. Comprobar Condiciones en un Iterador de Texto . . . . . . . . . . . . . . . . . . . . 16913.4.6. Comprobar la posicin en un Texto . . . . . . . . . . . . . . . . . . . . . . . . . . . 17013.4.7. Movimiento a travs del Texto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17113.4.8. Moverse a una Posicin Determinada . . . . . . . . . . . . . . . . . . . . . . . . . . 17213.4.9. Bsqueda en el Texto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172

    13.5. Marcas de Texto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17213.6. Etiquetas de Texto y Tablas de Etiquetas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173

    13.6.1. Etiquetas de Texto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173

    IV

  • NDICE GENERAL

    13.6.2. Tablas de Etiquetas de Texto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17513.7. Un ejemplo de Vista de Texto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 176

    14. Control de Vista de rbol (TreeView) 17914.1. Introduccin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17914.2. La Interfaz y Almacn de Datos TreeModel . . . . . . . . . . . . . . . . . . . . . . . . . . . 182

    14.2.1. Introduccin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18214.2.2. Creacin de Objetos TreeStore (rbol) y ListStore (lista) . . . . . . . . . . . . . . . . 18314.2.3. Cmo referirse a las filas de un modelo TreeModel . . . . . . . . . . . . . . . . . . . 183

    14.2.3.1. Caminos de rbol (Tree Paths) . . . . . . . . . . . . . . . . . . . . . . . . . 18414.2.3.2. Iteradores TreeIter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18414.2.3.3. Referencias persistentes a filas (TreeRowReferences) . . . . . . . . . . . . 185

    14.2.4. Adicin de filas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18514.2.4.1. Adicin de filas a un almacn de datos del tipo ListStore . . . . . . . . . . 18514.2.4.2. Adicin de filas a un almacn de datos del tipo TreeStore . . . . . . . . . 18614.2.4.3. Almacenes de datos de gran tamao . . . . . . . . . . . . . . . . . . . . . 186

    14.2.5. Eliminacin de Filas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18714.2.5.1. Eliminacin de filas de un almacn ListStore . . . . . . . . . . . . . . . . . 18714.2.5.2. Eliminacin de filas de un almacn TreeStore . . . . . . . . . . . . . . . . 187

    14.2.6. Gestin de los datos de las filas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18714.2.6.1. Establecemiento y obtencin de los valores de los datos . . . . . . . . . . 18714.2.6.2. Reorganizacin de filas en almacenes ListStore . . . . . . . . . . . . . . . 18814.2.6.3. Reorganizacin de filas en almacenes TreeStore . . . . . . . . . . . . . . . 18914.2.6.4. Gestin de mltiples filas . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189

    14.2.7. Soporte del protocolo de Python . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19114.2.8. Seales de TreeModel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19214.2.9. Ordenacin de filas de modelos TreeModel . . . . . . . . . . . . . . . . . . . . . . . 193

    14.2.9.1. La interfaz TreeSortable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19314.2.9.2. Clasificacin en almacenes ListStore y TreeStore . . . . . . . . . . . . . . . 194

    14.3. TreeViews (Vistas de rbol) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19414.3.1. Creacin de un TreeView (vista de rbol) . . . . . . . . . . . . . . . . . . . . . . . . 19414.3.2. Obtencin y establecimiento del Modelo de un TreeView . . . . . . . . . . . . . . . 19414.3.3. Definicin de las propiedades de un TreeView . . . . . . . . . . . . . . . . . . . . . 195

    14.4. Visualizadores de Celda (CellRenderer) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19614.4.1. Introduccin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19614.4.2. Tipos de Visualizadores CellRenderer . . . . . . . . . . . . . . . . . . . . . . . . . . 19714.4.3. Propiedade de un CellRenderer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19714.4.4. Atributos de un CellRenderer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19914.4.5. Funcin de Datos de Celda . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20014.4.6. Etiquetas de Marcado en CellRendererText . . . . . . . . . . . . . . . . . . . . . . . 20214.4.7. Celdas de Texto Editables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20314.4.8. Celdas Biestado Activables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20414.4.9. Programa de Ejemplo de Celda Editable and Activable . . . . . . . . . . . . . . . . 204

    14.5. TreeViewColumns (columnas de vista de rbol) . . . . . . . . . . . . . . . . . . . . . . . . . 20714.5.1. Creacin de TreeViewColumns (columnas de vista de rbol) . . . . . . . . . . . . . 20714.5.2. Gestin de los CellRenderers (Intrpretes de celda) . . . . . . . . . . . . . . . . . . 207

    14.6. Manipulacin de TreeViews . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20814.6.1. Gestin de las Columnas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20814.6.2. Expansin y Contraccin de Filas Hijas . . . . . . . . . . . . . . . . . . . . . . . . . 209

    14.7. Seales de TreeView . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20914.8. Selecciones TreeSelections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 210

    14.8.1. Obtencin de TreeSelection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21014.8.2. Modos de una seleccin TreeSelection . . . . . . . . . . . . . . . . . . . . . . . . . . 21014.8.3. Obtencin de la Seleccin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21014.8.4. Uso de una Funcin de TreeSelection . . . . . . . . . . . . . . . . . . . . . . . . . . 21114.8.5. Seleccin y Deseleccin de Filas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212

    14.9. Arrastrar y Soltar en TreeView . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21214.9.1. Reordenacin mediante Arrastrar y Soltar . . . . . . . . . . . . . . . . . . . . . . . 21214.9.2. Arrastar y Soltar Externo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212

    V

  • NDICE GENERAL

    14.9.3. Ejemplo de Arrastrar y Soltar en TreeView . . . . . . . . . . . . . . . . . . . . . . . 21414.10.TreeModelSort y TreeModelFilter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217

    14.10.1.TreeModelSort (Modelo de rbol Ordenado) . . . . . . . . . . . . . . . . . . . . . . 21714.10.2.TreeModelFilter (Modelo de rbol filtrado) . . . . . . . . . . . . . . . . . . . . . . . 218

    14.11.El Modelo de rbol Genrico (GenericTreeModel) . . . . . . . . . . . . . . . . . . . . . . . 22114.11.1.Visin general de GenericTreeMode . . . . . . . . . . . . . . . . . . . . . . . . . . . 22114.11.2.La Interfaz GenericTreeModel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22214.11.3.Adicin y Eliminacin de Filas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22514.11.4.Gestin de Memoria . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22714.11.5.Otras Interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22814.11.6.Utilizacin de GenericTreeModel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 228

    14.12.El Visualizador de Celda Genrico (GenericCellRenderer) . . . . . . . . . . . . . . . . . . . 229

    15. Nuevos Controles de PyGTK 2.2 23115.1. Portapapeles (Clipboard) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 231

    15.1.1. Creacin de un objeto Clipboard (Portapapeles) . . . . . . . . . . . . . . . . . . . . 23115.1.2. Utilizacin de Clipboards con elementos Entry, Spinbutton y TextView . . . . . . . 23115.1.3. Incorporacin de datos en un portapapeles . . . . . . . . . . . . . . . . . . . . . . . 23215.1.4. Obtencin de los Contenidos del Portapapeles . . . . . . . . . . . . . . . . . . . . . 23315.1.5. Ejemplo de Portapapeles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 234

    16. Nuevos Controles de PyGTK 2.4 23516.1. Objetos de Accin (Action) y Grupo de Acciones (ActionGroup) . . . . . . . . . . . . . . . 236

    16.1.1. Acciones (Actions) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23616.1.1.1. Creacin de acciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23616.1.1.2. Uso de acciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23716.1.1.3. Creacin de Controles intermedios (Proxy) . . . . . . . . . . . . . . . . . . 23816.1.1.4. Propiedades de Accin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24116.1.1.5. Acciones y Aceleradores . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24216.1.1.6. Acciones Conmutables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24316.1.1.7. Acciones con Exclusin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24316.1.1.8. Un ejemplo de Acciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . 244

    16.1.2. Grupos de Acciones (ActionGroups) . . . . . . . . . . . . . . . . . . . . . . . . . . . 24416.1.2.1. Creacin de grupos de acciones (ActionGroups) . . . . . . . . . . . . . . . 24416.1.2.2. Adicin de Acciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24516.1.2.3. Obtencin de iconos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24616.1.2.4. Control de las Acciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24616.1.2.5. Un ejemplo de grupo de acciones (ActionGroup) . . . . . . . . . . . . . . 24616.1.2.6. Seales de los grupos de acciones (ActionGroup) . . . . . . . . . . . . . . 247

    16.2. Controles de Lista Desplegable (ComboBox) y Lista Desplegable con Entrada (ComboBox-Entry) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24716.2.1. Controles ComboBox . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 247

    16.2.1.1. Uso Bsico de ComboBox . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24716.2.1.2. Uso Avanzado de ComboBox . . . . . . . . . . . . . . . . . . . . . . . . . 249

    16.2.2. Controles ComboBoxEntry . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25116.2.2.1. Uso Bsico de ComboBoxEntry . . . . . . . . . . . . . . . . . . . . . . . . 25116.2.2.2. Uso Avanzado de ComboBoxEntry . . . . . . . . . . . . . . . . . . . . . . 252

    16.3. Controles Botn de Color y de Fuente (ColorButton y FontButton) . . . . . . . . . . . . . . 25316.3.1. Control Botn de Color (ColorButton) . . . . . . . . . . . . . . . . . . . . . . . . . . 25316.3.2. Control Botn de Fuente (FontButton) . . . . . . . . . . . . . . . . . . . . . . . . . . 254

    16.4. Controles de Entrada con Completado (EntryCompletion) . . . . . . . . . . . . . . . . . . 25616.5. Controles de Expansin (Expander) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25816.6. Selecciones de Archivos mediante el uso de Controles basados en el Selector de Archivos

    FileChooser . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25916.7. El gestor de Interfaces de Usuario UIManager . . . . . . . . . . . . . . . . . . . . . . . . . 261

    16.7.1. Perspectiva general . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26116.7.2. Creacin de un gestor UIManager . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26216.7.3. Adicin y Eliminacin de Grupos de Acciones (ActionGroups) . . . . . . . . . . . 26216.7.4. Descripciones de la Interfaz de Usuario . . . . . . . . . . . . . . . . . . . . . . . . . 263

    VI

  • NDICE GENERAL

    16.7.5. Adicin y Eliminacin de Descripciones de Interfaz de Usuario . . . . . . . . . . . 26416.7.6. Acceso a los Controles de la Interfaz de Usuario . . . . . . . . . . . . . . . . . . . . 26516.7.7. Ejemplo sencillo de Gestor de Interfaz UIManager . . . . . . . . . . . . . . . . . . . 26616.7.8. Combinacin de Descripciones de Interfaz de Usuario . . . . . . . . . . . . . . . . 26716.7.9. Seales de UIManager . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 269

    17. Controles sin documentar 27117.1. Etiqueta de Aceleracin (Atajo) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27117.2. Men de Opciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27117.3. Elementos de Men . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 271

    17.3.1. Elemento de Men de Activacin . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27117.3.2. Elemento de Men de Exclusin Mtua . . . . . . . . . . . . . . . . . . . . . . . . . 27117.3.3. Elemento de Men de Separacin . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27117.3.4. Elemento de Men de Cascada . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 271

    17.4. Curvas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27117.5. Dilogo de Mensaje . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27117.6. Curva Gamma . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 271

    18. Establecimiento de Atributos de Controles 27318.1. Mtodos de Banderas de los Controles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27318.2. Mtodos de Visualizacin de Controles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27418.3. Atajos de Teclado de los Controles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27418.4. Mtodos relacionados con el Nombre de los Controles . . . . . . . . . . . . . . . . . . . . . 27518.5. Estilo de los Controles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 275

    19. Temporizadores, Entrada/Salida y Funciones de Inactividad 27919.1. Temporizadores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27919.2. Monitorizar la Entrada/Salida . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27919.3. Funciones de Inactividad . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 280

    20. Procesamiento Avanzado de Eventos y Seales 28120.1. Mtodos de Seales . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 281

    20.1.1. Conectar y Desconectar Manejadores de Seal . . . . . . . . . . . . . . . . . . . . . 28120.1.2. Bloqueo y Desbloqueo de Manejadores de Seal . . . . . . . . . . . . . . . . . . . . 28220.1.3. Emisin y Parada de Seales . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 282

    20.2. Emisin y Propagacin de Seales . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 282

    21. Tratamiento de Selecciones 28321.1. Descripcin General de la Seleccin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28321.2. Recuperar la Seleccin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28321.3. Proporcionar la Seleccin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 287

    22. Arrastrar y Soltar 29122.1. Descripcin General de Arrastrar y Soltar . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29122.2. Propiedades de Arrastrar y Soltar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29222.3. Mtodos de Arrastrar y Soltar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 292

    22.3.1. Configuracin del Control Origen . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29222.3.2. Seales en el Control Fuente . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29322.3.3. Configuracin de un Control Destino . . . . . . . . . . . . . . . . . . . . . . . . . . 29322.3.4. Seales en el Control Destino . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 294

    23. Ficheros rc de GTK+ 29923.1. Funciones para Ficheros rc . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29923.2. Formato de los Ficheros rc de GTK+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30023.3. Ejemplo de fichero rc . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 301

    VII

  • NDICE GENERAL

    24. Scribble: Un Ejemplo Sencillo de Programa de Dibujo 30524.1. Perspectiva General de Scribble . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30524.2. Manejo de Eventos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 305

    24.2.1. Scribble - Manejo de Eventos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31024.3. El Control del rea de Dibujo, y Dibujar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 312

    25. Trucos para Escribir Aplicaciones PyGTK 31525.1. El usario debera manejar la interfaz, no al contrario . . . . . . . . . . . . . . . . . . . . . . 31525.2. Separa el modelo de datos de la interfaz . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31525.3. Cmo separar los Mtodos de Retrollamada de los Manejadores de Seal . . . . . . . . . . 316

    25.3.1. Introduccin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31625.3.2. Herencia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31625.3.3. Herencia aplicada a PyGTK . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 316

    26. Contribuir 321

    27. Crditos 32327.1. Crditos Original de GTK+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 323

    28. Copyright del Tutorial y Nota de Permisos 325

    A. Seales de GTK 327A.1. gtk.Object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 327A.2. gtk.Widget . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 327A.3. GtkData . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 329A.4. gtk.Container . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 329A.5. gtk.Calendar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 329A.6. gtk.Editable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 329A.7. gtk.Notebook . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 330A.8. gtk.List . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 330A.9. gtk.MenuShell . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 330A.10.gtk.Toolbar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 330A.11.gtk.Button . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 331A.12.gtk.Item . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 331A.13.gtk.Window . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 331A.14.gtk.HandleBox . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 331A.15.gtk.ToggleButton . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 331A.16.gtk.MenuItem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 331A.17.gtk.CheckMenuItem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 331A.18.gtk.InputDialog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 332A.19.gtk.ColorSelection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 332A.20.gtk.StatusBar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 332A.21.gtk.Curve . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 332A.22.gtk.Adjustment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 332

    B. Ejemplos de Cdigo 333B.1. scribblesimple.py . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 333

    C. ChangeLog 337

    ndice alfabtico 345

    VIII

  • ndice de figuras

    2. Primeros Pasos2.1. Ventana Simple PyGTK . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62.2. Programa de ejemplo: Hola Mundo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8

    3. Avanzando3.1. Ejemplo mejorado de Hola Mundo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17

    4. Empaquetado de Controles4.1. Empaquetado: Cinco variaciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 204.2. Empaquetado con Spacing y Padding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 214.3. Empaquetado con pack_end() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 214.4. Empaquetado haciendo uso de una Tabla . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28

    6. El Control de Botn6.1. Botn con Pixmap y Etiqueta . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 366.2. Ejemplo de Botn Biestado . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 396.3. Ejemplo de Botn de Activacin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 416.4. Ejemplo de Botones de Exclusin Mtua . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43

    8. Controles de Rango8.1. Ejemplo de Controles de Rango . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52

    9. Miscelnea de Controles9.1. Ejemplos de Etiquetas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 589.2. Ejemplos de Botones con Flechas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 609.3. Ejemplo de Pistas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 629.4. Ejemplo de Barra de Progreso . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 659.5. Ejemplo de Imgenes en Botones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 699.6. Ejemplo de Pixmap en un Botn . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 729.7. Ejemplo de Ventana con Forma . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 739.8. Ejemplo de Reglas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 789.9. Ejemplo de Barra de Estado . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 809.10. Ejemplo de Entrada . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 829.11. Ejemplo de Botn Aumentar/Disminuir . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 869.12. Ejemplo de Calendario . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 929.13. Ejemplo de Dilogo de Seleccin de Color . . . . . . . . . . . . . . . . . . . . . . . . . . . . 989.14. Ejemplo de Seleccin de Ficheros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1019.15. Dilogo de Seleccin de Fuentes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102

    10. Controles Contenedores10.1. Ejemplo de Caja de Eventos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10510.2. Ejemplo de Fijo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10710.3. Ejemplo de Disposicin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11010.4. Ejemplo de Marco . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11210.5. Ejemplo de Marco Proporcional . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11410.6. Ejemplo de Panel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11610.7. Ejemplo de Ventana de Desplazamiento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11910.8. Ejemplo de Barra de Herramientas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129

    IX

  • NDICE DE FIGURAS NDICE DE FIGURAS

    10.9. Ejemplo de Fichas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131

    11. Control Men11.1. Ejemplo de Men . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13911.2. Ejemplo de Factoria de Elementos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142

    12. rea de Dibujo12.1. Ejemplo de rea de Dibujo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152

    13. Control de Vista de Texto13.1. Ejemplo bsico de Vista de Texto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16013.2. Ejemplo de Vista de Texto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177

    14. Control de Vista de rbol (TreeView)14.1. Programa elemental de ejemplo de TreeView . . . . . . . . . . . . . . . . . . . . . . . . . . 18214.2. TreeViewColumns con CellRenderers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19614.3. Funcin de Datos de Celda . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20114.4. Ejemplo de Listado de Archivos Utilizando Funciones de Datos de Celda . . . . . . . . . 20214.5. Etiquetas de Marcado para CellRendererText . . . . . . . . . . . . . . . . . . . . . . . . . . 20314.6. Celdas Editables y Activables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20714.7. Flecha de Expansin en la segunda Columna . . . . . . . . . . . . . . . . . . . . . . . . . . 20914.8. Ejemplo de Arrastrar y Soltar en TreeView . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21614.9. Ejemplo de TreeModelSort . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21814.10.Ejemplo de Visibilidad en TreeModelFilter . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22014.11.Programa de Ejemplo de Modelo de rbol Genrico . . . . . . . . . . . . . . . . . . . . . . 225

    15. Nuevos Controles de PyGTK 2.215.1. Programa de ejemplo de Portapapeles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 234

    16. Nuevos Controles de PyGTK 2.416.1. Ejemplo Simple de Accin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23816.2. Ejemplo Bsico de Accin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24116.3. Ejemplo de Acciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24416.4. Ejemplo de ActionGroup . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24716.5. ComboBox Bsica . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24816.6. ComboBox con una Disposicin Asociada . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25016.7. ComboBoxEntry Bsica . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25216.8. Ejemplo de Botn de Color - ColorButton . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25416.9. Ejemplo de Botn de Fuente - FontButton . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25616.10.Entrada con Completado (EntryCompletion) . . . . . . . . . . . . . . . . . . . . . . . . . . 25716.11.Control de Expansin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25916.12.Ejemplo de Seleccin de Archivos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26016.13.Programa sencillo de Gestor de Interfaz de Usuario UIManager . . . . . . . . . . . . . . . 26716.14.Ejemplo UIMerge . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 269

    21. Tratamiento de Selecciones21.1. Ejemplo de Obtencin de la Seleccin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28521.2. Ejemplo de Fijar la Seleccin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 288

    22. Arrastrar y Soltar22.1. Ejemplo de Arrastrar y Soltar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 295

    X

  • NDICE DE FIGURAS NDICE DE FIGURAS

    24. Scribble: Un Ejemplo Sencillo de Programa de Dibujo24.1. Ejemplo de Programa de Dibujo Scribble . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30524.2. Ejemplo sencillo - Scribble . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 311

    XI

  • ndice de cuadros

    22. Arrastrar y Soltar22.1. Seales del Control Fuente . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29322.2. Seales del Control Destino . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 295

    XIII

  • ResumenEste tutorial describe el uso del mdulo de Python PyGTK.

  • Captulo 1

    Introduccin

    PyGTK 2.0 es un conjunto de mdulos que componen una interfaz Python para GTK+ 2.0. En elresto de este documento cuando se menciona PyGTK se trata de la versin 2.0 o posterior de PyGTK,y en el caso de GTK+, tambin a su versin 2.0 y siguientes. El sitio web de referencia sobre PyGTK eswww.pygtk.org. El autor principal de PyGTK es:

    James Henstridge [email protected]

    que es ayudado por los desarrolladores citados en el archivo AUTHORS de la distribucin PyGTK ypor la comunidad PyGTK.

    Python es un lenguaje de programacin interpretado, ampliable y orientado a objetos que se dis-tribuye con un amplio conjunto de mdulos que permiten el acceso a un gran nmero de servicios delsistema operativo, servicios de internet (como HTML, XML, FTP, etc.), grficos (incluidos OpenGL, TK,etc.), funciones de manejo de cadenas, servicios de correo (IMAP, SMTP, POP3, etc.), multimedia (audio,JPEG) y servicios de criptografa. Existen adems multitud de mdulos proporcionados por tercerosque aaden otros servicios. Python se distribuye bajo trminos similares a los de la licencia GPL y estdisponible para los sistemas operativos Linux, Unix, Windows y Macintosh. En www.python.org hayms informacion disponible sobre Python. Su autor principal es:

    Guido van Rossum [email protected]

    GTK+ (GIMP Toolkit) es una librera que permite crear interfaces grficas de usuario. Se distribuyebajo la licencia LGPL, por lo que posibilita el desarrollo de software abierto, software libre, e inclusosoftware comercial no libre que use GTK sin necesidad de pagar licencias o derechos.

    Se le conoce como el toolkit de GIMP porque originalmente se escribi para desarrollar el Programade Manipulacin de Imgenes de GNU GIMP, pero GTK+ se usa ya en numerosos proyectos de software,includo el proyecto de escritorio GNOME (Entorno de Modelo de Objetos orientados a Red). GTK+ estdiseada sobre GDK (Kit de Dibujo de GIMP) que, bsicamente, es una abstraccin de las funciones debajo nivel que acceden al sistema de ventanas (Xlib en el caso del sistema de ventanas X). Los principalesautores de GTK+ son:

    Peter Mattis [email protected]

    Spencer Kimball [email protected]

    Josh MacDonald [email protected]

    Actualmente GTK+ es mantenida por:

    Owen Taylor [email protected]

    Tim Janik [email protected]

    GTK+ es fundamentalmente un interfaz orientada a objetos para programadores de aplicaciones(API). Aunque est escrita completamente en C, est implementada usando la idea de clases y funcionesde retrollamada (punteros a funcin).

    Existe un tercer componente, llamado Glib, que contiene diversas funciones que reemplazan algunasllamadas estandard, as como funciones adicionales para manejar listas enlazadas, etc. Las funcionesde reemplazo se usan para aumentar la portabilidad de GTK+ ya que algunas de las funciones que

    1

  • CAPTULO 1. INTRODUCCIN 1.1. EXPLORACIN DE PYGTK

    implementa no estn disponibles o no son estndar en otros UNIX, tales como g_strerror(). Otrasincluyen mejoras a las versiones de libc, tales como g_malloc, que posee capacidades de depuracinmejoradas.

    Desde su versin 2.0, GLib incluye el sistema de tipos que forma la base de la jerarqua de clases deGTK+, el sistema de seales usado en sta, una API de hebras que abstrae las diferentes APIs nativaspara programacin multihilo en las diversas plataformas, y la capacidad de cargar mdulos.

    Como ltimo componente, GTK+ usa la librera Pango para la salida de texto internacionalizado.Este tutorial describe la interfaz de Python con GTK+ y est basado en el tutorial de GTK+ 2.0 escrito

    por Tony Gale e Ian Main. En l se intenta documentar en la medida posible todo PyGTK, pero en ningncaso es completo.

    Este tutorial presupone algn conocimiento previo de Python, as de cmo se crean y ejecutan pro-gramas escritos en Python. Si no se est familiarizado con Python, es recomendable previamente lalectura del Tutorial de Python. Este tutorial no presupone ningn conocimiento previo sobre GTK+ ysi se utiliza PyGTK para aprender GTK+ sera interesante recibir comentarios acerca de este tutorial, yqu aspectos resultan problemticos. Este tutorial no describe cmo compilar o instalar Python, GTK+o PyGTK.

    Este tutorial est basado en:

    GTK+ desde la versin 2.0 hasta la 2.4

    Python 2.2

    PyGTK desde la versin 2.0 hasta la 2.4

    Los ejemplos se escribieron y probaron en una RedHat 9.0.Este documento est "en obras". Por favor, consltese www.pygtk.org para localizar las actualiza-

    ciones.Me gustara mucho escuchar los problemas que aparezcan al aprender PyGTK a partir de este docu-

    mento, y se aprecian los comentarios sobre cmo mejorarlo. Por favor, mira la seccin Cmo Contribuirpara ms informacin. Si encuentra fallos, por favor rellene un informe de fallo en bugzilla.gnome.orgen el proyecto pygtk. Para ello, la informacin que se encuentra en www.pygtk.org sobre Bugzilla puederesultar de gran utilidad.

    El manual de referencia de PyGTK 2.0 se encuentra disponible en http://www.pygtk.org/pygtkreference.Dicho manual describe detalladamente las clases de PyGTK y, por ahora, slo se encuentra disponibleen ingls.

    La pgina web de PyGTK (www.pygtk.org) contiene otros recursos tiles para aprender PyGTK,incluido un enlace a la extensa FAQ (Lista de Preguntas Frecuentes, tambin en ingls nicamente), yotros artculos y cursos, as como una lista de correo activa y un canal IRC (consltese www.pygtk.orgpara los detalles).

    1.1. Exploracin de PyGTK

    Johan Dahlin escribi un pequeo programa en Python (pygtkconsole.py) que se ejecuta en Linuxy permite la exploracin interactiva de PyGTK. Ese progama proporciona una interfaz de intrpreteinteractivo al estilo de la de Python, que se comunica con un proceso hijo que ejecuta los comandosintroducidos. Los mdulos PyGTK se cargan por defecto al arrancar el programa. Un ejemplo simple desesin es:

    moe: 96:1095$ pygtkconsole.pyPython 2.2.2, PyGTK 1.99.14 (Gtk+ 2.0.6)Interactive console to manipulate GTK+ widgets.>>> w=Window()>>> b=Button(Hola)>>> w.add(b)>>> def hola(b):... print "Hola Mundo!"...>>> b.connect(clicked, hola)5>>> w.show_all()>>> Hola Mundo!

    2

  • CAPTULO 1. INTRODUCCIN 1.1. EXPLORACIN DE PYGTK

    Hola Mundo!Hola Mundo!

    >>> b.set_label("Hola a todos")>>>

    En este ejemplo se crea una ventana que contiene un botn que imprime un mensaje (Hola Mundo!)cuando se hace clic en l. El programa permite probar as fcilmente los diversos controles de GTK+ ysus interfaces PyGTK.

    Tambin es til el programa desarrollado por Brian McErlean para la receta de Activestate 65109 jun-to con algunas modificaciones para que funcione con PyGTK 2.X. En este curso lo llamamos gpython.pyy funciona de forma parecida al programa pygtkconsole.py.

    NOTA

    Estos dos programas no funcionan en Microsoft Windows porque necesitan funcionesespecficas de Unix.

    3

  • Captulo 2

    Primeros Pasos

    Para empezar nuestra introduccin a PyGTK, comenzaremos con el programa ms simple posible.Este programa (base.py) crear una ventana de 200x200 pxeles y no es posible salir de l excepto termi-nando el proceso desde la consola.

    1 #!/usr/bin/env python23 # example base.py45 import pygtk6 pygtk.require(2.0)7 import gtk89 class Base:

    10 def __init__(self):11 self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)12 self.window.show()1314 def main(self):15 gtk.main()1617 print __name__18 if __name__ == "__main__":19 base = Base()20 base.main()

    Se puede ejecutar el programa anterior escribiendo en la lnea de rdenes:

    python base.py

    Si base.py es hecho ejecutable y se puede encontrar en la variable PATH, es posible ejecutarlo usando:

    base.py

    En este caso, la lnea 1 pedir al intrprete de Python que ejecute base.py. Las lneas 5-6 ayudan adiferenciar entre las distintas versiones de PyGTK que puedan estar instaladas en el equipo. Estas lneasindican que se desea usar la versin 2.0 de PyGTK, que comprende todas las versiones de PyGTK con2 como nmero principal. Ello impide que el programa utilice versiones anteriores de PyGTK, en casode que se encuentren instaladas en el sistema. Las lneas 18-20 comprueban si la variable __name__ es"__main__", lo cual indica que el programa est siendo ejecutado directamente por python y no estsiendo importado en un intrprete Python. En el primer caso el programa crea una nueva instancia dela clase Base y guarda una referencia a ella en la variable base. Despus llama la funcin main() parainiciar el bucle de procesamiento de eventos de GTK.

    Una ventana similar a Figura 2.1 debera aparecer en tu pantalla.

    5

  • CAPTULO 2. PRIMEROS PASOS

    Figura 2.1 Ventana Simple PyGTK

    La primera lnea permite al programa base.py ser invocado desde una consola Linux o Unix asum-iendo que python se encuentre en el PATH. Esta lnea aparecer como primera lnea en todos los progra-mas de ejemplo.

    Las lneas 5-7 importan el mdulo PyGTK 2 e inicializan el entorno GTK+. El mdulo PyGTK definelas interfaces Python de las funciones GTK+ que se usarn en el programa. Para quienes estn famil-iarizados con GTK+ hay que advertir que la inicializacin incluye la llamada a la funcin gtk_init().Tambin se configuran algunas cosas por nosotros, tales como el visual por defecto, el mapa de col-ores, manejadores de seales predeterminados. Asimismo comprueba los argumentos que se pasan alprograma desde la lnea de comandos, en busca de alguno entre:

    --gtk-module

    --g-fatal-warnings

    --gtk-debug

    --gtk-no-debug

    --gdk-debug

    --gdk-no-debug

    --display

    --sync

    --name

    --class

    En este caso, los borra de la lista de argumentos y deja los no coincidentes que no reconoce paraque el programa lo procese o ignore. El anterior conjunto de argumentos son los que aceptan de formaestndar todos los programas GTK+.

    Las lneas 9-15 definen una clase de Python llamada Base que define un mtodo de inicializacinde instancia __init__(). La funcin __init__() crea una ventana de nivel superior (lnea 11) y ordena aGTK+ que la muestre (lnea 12). La gtk.Window se crea en la lnea 11 con el argumento gtk.WIN-DOW_TOPLEVEL que indica que se desea una ventana sometida a las decoraciones y posicionamientodel manejador de ventanas. En vez de crear una ventana de tamao 0x0, una ventana sin hijos tiene untamao predeterminado de 200x200 de forma que se pueda manipular.

    6

  • CAPTULO 2. PRIMEROS PASOS 2.1. HOLA MUNDO EN PYGTK

    Las lneas 14-15 definen el mtodo main() que llama a la funcin PyGTK main(), que invoca el bucleprincipal de procesamiento de eventos de GTK+ para manejar eventos de ratn y de teclado, as comoeventos de ventana.

    Las lneas 18-20 permiten al programa comenzar automticamente si es llamado directamente opasado como argumento al intrprete de Python. En estos casos, el nombre de programa que hay enla variable __name__ ser la cadena "__main__" y el cdigo entre las lneas 18-20 se ejecutar. Si elprograma se carga en un intrprete de Python en ejecucin, las lneas 18-20 no sern ejecutadas.

    La lnea 19 crea una instancia de la clase Base llamada base. Crea una gtk.Window y la muestracomo resultado.

    La lnea 20 llama al mtodo main() de la clase Base, la cual comienza el bucle de procesamiento deeventos de GTK+. Cuando el control llega a este punto, GTK+ se dormir a la espera de eventos de lasX (como pulsaciones de teclas o botones), alarmas, o notificaciones de entrada/salida de ficheros. En elejemplo, sin embargo, los eventos son ignorados.

    2.1. Hola Mundo en PyGTK

    Ahora seguimos con un programa con un control (un botn). Es la versin PyGTK del clsico pro-grama hola mundo (helloworld.py ).

    1 #!/usr/bin/env python23 # ejemplo helloworld.py45 import pygtk6 pygtk.require(2.0)7 import gtk89 class HelloWorld:

    1011 # Esta es una funcin de retrollamada. Se ignoran los argumentos de

    datos12 # en este ejemplo. Ms sobre retrollamadas ms abajo.13 def hello(self, widget, data=None):14 print "Hello World"1516 def delete_event(self, widget, event, data=None):17 # Si se devuelve FALSE en el gestor de la seal "delete_event",18 # GTK emitir la seal "destroy". La devolucin de TRUE significa19 # que no se desea la destruccin de la ventana.20 # Esto sirve para presentar dilogos como: Est seguro de que

    desea salir?21 #22 print "delete event occurred"2324 # Si se cambia FALSE a TRUE la ventana principal no se25 # destruir con "delete_event".26 return gtk.FALSE2728 # Otra retrollamada29 def destroy(self, widget, data=None):30 gtk.main_quit()3132 def __init__(self):33 # se crea una ventana nueva34 self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)3536 # Cuando se enva a una ventana la seal "delete_event" (esto lo

    hace37 # generalmente el gestor de ventanas, usualmente con "cerrar", o

    con el icono38 # de la ventana de ttulo), pedimos que llame la funcin

    delete_event ()

    7

  • CAPTULO 2. PRIMEROS PASOS 2.1. HOLA MUNDO EN PYGTK

    39 # definida arriba. Los datos pasados a la retrollamada son40 # NULL y se ignoran en la funcin de retrollamada.41 self.window.connect("delete_event", self.delete_event)4243 # Conectamos el evento "destroy" a un manejador de seal.44 # Este evento sucede cuando llamamos gtk_widget_destroy() para la

    ventana,45 # o si devolvemos FALSE en la retrollamada "delete_event".46 self.window.connect("destroy", self.destroy)4748 # Establece el grosor del borde de la ventana.49 self.window.set_border_width(10)5051 # Crea un nuevo botn con la etiqueta "Hello World".52 self.button = gtk.Button("Hello World")5354 # Cuando el botn recibe la seal "clicked", llamar la55 # funcin hello() a la que pasa None como argumento. La funcin

    hello()56 # se define ms arriba.57 self.button.connect("clicked", self.hello, None)5859 # Esto causar la destruccin de la ventana al llamar a60 # gtk_widget_destroy(window) cuando se produzca "clicked". De

    nuevo,61 # la seal podra venir de aqu o del gestor de ventanas.62 self.button.connect_object("clicked", gtk.Widget.destroy, self.

    window)6364 # Esto empaqueta el botn en la ventana (un contenedor de GTK+).65 self.window.add(self.button)6667 # El paso final es mostrar el control recin creado.68 self.button.show()6970 # y la ventana71 self.window.show()7273 def main(self):74 # Todas las aplicaciones de PyGTK deben tener una llamada a gtk.

    main(). Aqu se deja75 # el control y se espera que suceda un evento (como un evento de

    teclado o ratn).76 gtk.main()7778 # Si el programa se ejecuta directamente o se pasa como argumento al

    intrprete79 # de Python, entonces se crea una instancia de HelloWorld y se muestra80 if __name__ == "__main__":81 hello = HelloWorld()82 hello.main()

    Figura 2.2 muestra la ventana creada por helloworld.py.

    Figura 2.2 Programa de ejemplo: Hola Mundo

    8

  • CAPTULO 2. PRIMEROS PASOS 2.2. TEORA DE SEALES Y RETROLLAMADAS

    Las variables y funciones que se definen en el mdulo PyGTK se llaman de la forma gtk.*. Porejemplo, el programa helloworld.py usa:

    gtk.FALSEgtk.mainquit()gtk.Window()gtk.Button()

    del mdulo PyGTK. En futuras secciones no se especificar el prefijo del mdulo gtk, pero se darpor asumido. Naturalmente, los programas de ejemplo usarn los prefijos del mdulo.

    2.2. Teora de Seales y Retrollamadas

    NOTA

    En la versin 2.0 de GTK+, el sistema de seales se ha movido de GTK+ a GLib. No en-traremos en detalles sobre las extensiones que GLib 2.0 tiene en relacin con el sistemade seales de GTK 1.2. Las diferecias no deberan notarse en el uso de PyGTK.

    Antes de entrar en detalle en helloworld.py, discutiremos las seales y las retrollamadas. GTK+ esuna biblioteca orientada a eventos, lo que significa que se dormir en la funcin gtk.main() hasta que unevento ocurra y el control pase a la funcin apropiada.

    Esta delegacin del control se realiza usando la idea de "seales". (Ntese que estas seales no sonlas mismas que las seales de los sistemas Unix, y no se implementan usando stas, aunque la termi-nologa es casi idntica) Cuando ocurre un evento, como cuando presionamos un botn del ratn, laseal apropiada se "emite" por el el control que fu presionado. As es cmo GTK+ hace la mayorade su trabajo til. Hay seales que todos los controles heredan, como "destroy", y hay seales que sonespecficas de cada control, como "toggled" en el caso de un botn de activacin.

    Para hacer que un botn realice una accin, debemos configurar un manejador de seales que captureestas seales y llame a la funcin apropiada. Esto se hace usando un mtodo de gtk.Widget (heredadode la clase GObject) como por ejemplo:

    handler_id = object.connect(name, func, func_data)

    donde object es la instancia de gtk.Widget (un control) que estar emitiendo la seal, y el primerargumento name es una cadena que contiene el nombre de la seal que se desea capturar. El segundoargumento, func, es la funcin que se quiere llamar cuando se produce el evento. El tercer argumento,func_data, son los datos que se desean pasar a la funcin func. El mtodo devuelve un handler_id quese puede usar para desconectar o bloquear el uso del manejador.

    La funcin especificada en el tercer argumento se llama "funcin de retrollamada", y generalmentetiene la forma:

    def callback_func(widget, callback_data):

    donde el primer argumento ser una referencia al widget (control) que emiti la seal, y el segun-do (callback_data) una referencia a los datos dados como ltimo argumento en el mtodo connect()mostrado antes.

    Si la funcin de retrollamada es un mtodo de un objeto entonces tendr la forma general siguiente:

    def callback_meth(self, widget, callback_data):

    donde self es la instancia del objeto que invoca este mtodo. Esta es la forma usada en el programade ejemplo helloworld.py.

    9

  • CAPTULO 2. PRIMEROS PASOS 2.3. EVENTOS

    NOTA

    La forma anterior de declaracin de una funcin de retrollamada a seales es slo unagua general, ya que las seales especficas de los distintos controles generan diferentesparmetros de llamada.

    Otra llamada que se usa en el ejemplo helloworld.py es:

    handler_id = object.connect_object(name, func, slot_object)

    connect_object() es idntica a connect(), exceptuando que una funcin de retrollamada slo usa unargumento, y un mtodo de retrollamada, dos argumentos:

    def callback_func(object)def callback_meth(self, object)

    donde object normalmente es un control. connect_object() permite usar los mtodos de controlesPyGTK qu solo admiten un argumento (self) como manejadores de seales.

    2.3. Eventos

    Adems del mecanismo de seales descrito anteriormente, hay un conjunto de eventos que reflejanel mecanismo de eventos de X. Las retrollamadas tambin se pueden conectar a estos eventos. Estoseventos son:

    eventbutton_press_eventbutton_release_eventscroll_eventmotion_notify_eventdelete_eventdestroy_eventexpose_eventkey_press_eventkey_release_evententer_notify_eventleave_notify_eventconfigure_eventfocus_in_eventfocus_out_eventmap_eventunmap_eventproperty_notify_eventselection_clear_eventselection_request_eventselection_notify_eventproximity_in_eventproximity_out_eventvisibility_notify_eventclient_eventno_expose_eventwindow_state_event

    Para conectar una funcin de retrollamada a uno de estos eventos se usa el mtodo connect(), comose ha dicho anteriormente, usando uno de los nombres de eventos anteriores en el parmetro name. Lafuncin (o mtodo) de retrollamada para eventos es ligeramente diferente de la usada para seales:

    def callback_func(widget, event, callback_data):

    def callback_meth(self, widget, event, callback_data):

    10

  • CAPTULO 2. PRIMEROS PASOS 2.3. EVENTOS

    gdk.Event es un tipo de objetos Python cuyos atributos de tipo indicarn cul de los eventos an-teriores ha ocurrido. Los otros atributos del evento dependern del tipo de evento. Los valores posiblespara los tipos son:

    NOTHINGDELETEDESTROYEXPOSEMOTION_NOTIFYBUTTON_PRESS_2BUTTON_PRESS_3BUTTON_PRESSBUTTON_RELEASEKEY_PRESSKEY_RELEASEENTER_NOTIFYLEAVE_NOTIFYFOCUS_CHANGECONFIGUREMAPUNMAPPROPERTY_NOTIFYSELECTION_CLEARSELECTION_REQUESTSELECTION_NOTIFYPROXIMITY_INPROXIMITY_OUTDRAG_ENTERDRAG_LEAVEDRAG_MOTIONDRAG_STATUSDROP_STARTDROP_FINISHEDCLIENT_EVENTVISIBILITY_NOTIFYNO_EXPOSESCROLLWINDOW_STATESETTING

    Para acceder a estos valores se aade el prefijo gtk.gdk. al tipo de evento. Por ejemplo, gtk.gdk-.DRAG_ENTER.

    Por tanto, para conectar una funcin de retrollamada a uno de estos eventos se usara algo como:

    button.connect("button_press_event", button_press_callback)

    Esto asume que button es un control gtk.Button. Entonces, cuando el ratn est sobre el botny se pulse un botn del ratn, se llamar a la funcin button_press_callback. Esta funcin se puededefinir as:

    def button_press_callback(widget, event, data):

    El valor que devuelve esta funcin indica si el evento debe ser propagado por el sistema de manejo deeventos GTK+. Devolviendo gtk.TRUE indicamos que el evento ha sido procesado, y que no debe serpropagado. Devolviendo gtk.FALSE se continua el procesamiento normal del evento. Es aconsejableconsultar la seccin Procesamiento Avanzado de Eventos y Seales para obtener ms detalles sobre elsistema de propagacin.

    Las APIs de seleccin y arrastrar y soltar de GDK tambin emiten unos cuantos eventos que se refle-jan en GTK+ por medio de seales. Consulta Seales en el Control de Orgen y Seales en el Control deDestino para obtener ms detalles sobre la sintaxis de las funciones de retrollamada para estas seales:

    selection_receivedselection_getdrag_begin_eventdrag_end_event

    11

  • CAPTULO 2. PRIMEROS PASOS 2.4. HOLA MUNDO PASO A PASO

    drag_data_deletedrag_motiondrag_dropdrag_data_getdrag_data_received

    2.4. Hola Mundo Paso a Paso

    Ahora que ya conocemos la teora general, vamos a aclarar el programa de ejemplo helloworld.pypaso a paso.

    Las lneas 9-76 definen la clase HelloWorld, que contiene todas las retrollamadas como mtodos deobjeto y el mtodo de inicializacin de objetos. Examinemos los mtodos de retrollamada:

    Las lneas 13-14 definen el mtodo de retrollamada hello() que ser llamado al pulsar el botn.Cuando se llama a este mtodo, se imprime "Hello World" en la consola. En el ejemplo ignoramos losparmetros de la instancia del objeto, el control y los datos, pero la mayora de las retrollamadas losusan. El parmetro data se define con un valor predeterminado igual a None porque PyGTK no pasarningn valor para los datos si no son incluidos en la llamada a connect(); esto producira un error yaque la retrollamada espera tres argumentos y nicamente recibe dos. La definicin de un valor por de-fecto None permite llamar a la retrollamada con dos o tres parmetros sin ningn error. En este casoel parmetro de datos podra haberse omitido, ya que el mtodo hello() siempre ser llamado con slodos parmetros (nunca se usan los datos de usuario). En el siguiente ejemplo usaremos el argumento dedatos para saber qu botn fue pulsado.

    def hello(self, widget, data=None):print "Hello World"

    La siguiente retrollamada (lneas 16-26) es un poco especial. El evento "delete_event" se producecuando el manejador de ventanas manda este evento al programa. Tenemos varias posibilidades encuanto a qu hacer con estos eventos. Podemos ignorarlos, realizar algun tipo de respuesta, o simple-mente cerrar el programa.

    El valor que se devuelva en esta retrollamada le permite a GTK+ saber qu accin realizar. Si de-volvemos TRUE hacemos saber que no queremos que se emita la seal "destroy", y as nuestra aplicacinsigue ejecutndose. Si devolvemos FALSE pedimos que se emita la seal "destroy", que a su vez lla-mar a nuestro manejador de la seal "destroy". Ntese que se han quitado los comentarios para mayorclaridad.

    def delete_event(widget, event, data=None):print "delete event occurred"return gtk.FALSE

    El mtodo de retrollamada destroy() (lneas 29-30) hace que el programa termine mediante la lllama-da a gtk.main_quit(). Esta funcin indica a GTK que debe salir de la funcin gtk.main() cuando elcontrol le sea transferido.

    def destroy(widget, data=None):gtk.main_quit()

    Las lneas 32-71 definen el mtodo de inicializacin de instancia __init__() del objeto HelloWorld,el cual crea la ventana y los controles que se usan en el programa.

    La lnea 34 crea una nueva ventana, pero no se muestra directamente hasta que comunicamos aGTK+ que lo haga, casi al final del programa. La referencia a la ventana se guarda en un atributo deinstancia (self.window) para poder acceder a ella despus.

    self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)

    Las lneas 41 y 46 ilustran dos ejemplos de cmo conectar un manejador de seal a un objeto, eneste caso a window. Aqu se captura el evento "delete_event" y la seal "destroy". El primero se emitecuando cerramos la ventana a travs del manejador de ventanas o cuando usamos la llamada al mtododestroy() de gtk.Widget. La segunda se emite cuando, en el manejador de "delete_event", devolvemosFALSE.

    12

  • CAPTULO 2. PRIMEROS PASOS 2.4. HOLA MUNDO PASO A PASO

    self.window.connect("delete_event", self.delete_event)self.window.connect("destroy", self.destroy)

    La lnea 49 establece un atributo de un objeto contenedor (en este caso window) para que tengaun rea vaca de 10 pxeles de ancho a su alrededor en donde no se site ningn control. Hay otrasfunciones similares que se tratarn en la seccin Establecimiento de Atributos de Controles

    self.window.set_border_width(10)

    La lnea 52 crea un nuevo botn y guarda una referencia a l en self.button. El botn tendr laetiqueta "Hello World" cuando se muestre.

    self.button = gtk.Button("Hello World")

    En la lnea 57 conectamos un manejador de seal al botn, de forma que, cuando emita la seal"clicked", se llame a nuestro manejador de retrollamada hello(). No pasamos ningn dato a hello() asque simplemente se entrega None como dato. Obviamente, la seal "clicked" se emite al hacer clic en elbotn con el cursor del ratn. El valor del parmetro de los datos None no es imprescindible y podraomitirse. La retrollamada se llamar con un parmetro menos.

    self.button.connect("clicked", self.hello, None)

    Tambin vamos a usar este botn para salir del programa. La lnea 62 muestra cmo la seal "destroy"puede venir del manejador de ventanas, o de nuestro programa. Al hacer clic en el botn, al igual queantes, se llama primero a la retrollamada hello(), y despus a la siguiente en el orden en el que han sidoconfiguradas. Se pueden tener todas las retrollamadas que sean necesarias, y se ejecutarn en el ordenen el que se hayan conectado.

    Como queremos usar el mtodo destroy() de la clase gtk.Widget que acepta un argumento (elcontrol que se va a destruir - en este caso window), utilizamos el mtodo connect_object() y le pasamosla referencia a la ventana. El mtodo connect_object() organiza el primer argumento de la retrollamadapara que sea window en vez del botn.

    Cuando se llama el mtodo destroy() de la clase gtk.Widget se emite la seal "destroy" desde laventana, lo que a su vez provocar la llamada al mtodo destroy() de la clase HelloWorld que terminael programa.

    self.button.connect_object("clicked", gtk.Widget.destroy, self.window)

    La lnea 65 es una llamada de colocacin, que se explicar en profundidad ms tarde, en Colocacinde Controles, aunque es bastante fcil de entender. Simplemente indica a GTK+ que el botn debesituarse en la ventana en donde se va a mostrar. Ha de tenerse en cuenta que un contenedor GTK+nicamente puede contener un control. Otros controles, descritos ms adelante, estn diseados paraposicionar varios controles de otras maneras.

    self.window.add(self.button)

    Ahora lo tenemos todo configurado como queremos. Con todos los manejadores de seales, y elbotn situado en la ventana donde debera estar, pedimos a GTK (lneas 66 y 69) que muestre los con-troles en pantalla. El control de ventana se muestra en ltimo lugar, para que la ventana entera aparezcade una vez y no primero la ventana y luego el botn dentro de ella dibujndose. Sin embargo, con unejemplo tan simple, sera difcil apreciar la diferencia.

    self.button.show()

    self.window.show()

    Las lneas 73-75 definen el mtodo main() que llama a la funcin gtk.main()

    def main(self):gtk.main()

    Las lneas 80-82 permiten al programa ejecutarse automticamente si es llamado directamente o co-mo argumento del intrprete de python. La lnea 81 crea una instancia de la clase HelloWorld y guardauna referencia a ella en la variable hello. La lnea 82 llama al mtodo main() de la clase HelloWorldpara empezar el bucle de procesamiento de eventos GTK.

    13

  • CAPTULO 2. PRIMEROS PASOS 2.4. HOLA MUNDO PASO A PASO

    if __name__ == "__main__":hello = HelloWorld()hello.main()

    Ahora, cuando hagamos clic con el botn del ratn en el botn GTK, el control emitir una seal"clicked". Para poder usar esta informacin, nuestro programa configura un manejador de seal quecapture esta seal, la cual llama a la funcin que decidamos. En nuestro ejemplo, cuando se pulsa elbotn que hemos creado, se llama el mtodo hello() con un argumento None, y despus se llama elsiguiente manejador para esta seal. El siguiente manejador llama a la funcin destroy() del control conla ventana como su argumento y de esta manera causa que la ventana emita la seal "destroy", que escapturada y llama al mtodo destroy() de la clase HelloWorld

    Otra funcin de los eventos es usar el manejador de ventanas para eliminar la ventana, lo que causarque se emita "delete_event". Esto llamar a nuestro manejador de "delete_event". Si devolvemos TRUEaqu, la ventana se quedar como si nada hubiera pasado. Devolviendo FALSE har que GTK+ emita laseal "destroy", que llama a la retrollamada "destroy" de la clase HelloWorld cerrando GTK+.

    14

  • Captulo 3

    Avanzando

    3.1. Ms sobre manejadores de seales

    Veamos otra vez la llamada a connect() .

    object.connect(name, func, func_data)

    El valor de retorno de connect() es un nmero entero que identifica la retrollamada. Como ya se hamencionado, es posible disponer de tantas retrollamadas por seal como sea necesario, y cada una deellas se ejecutar por turnos, en el mismo orden de conexin.

    Este identificador permite eliminar la retrollamada de la lista de retrollamadas activas mediante elmtodo:

    object.disconnect(id)

    As, pasando el identificador devuelto por los mtodos de conexin, es posible desconectar un mane-jador de seal.

    Tambin es posible deshabilitar temporalmente un manejador de seal mediante los mtodos han-dler_block() y handler_unblock().

    object.handler_block(handler_id)

    object.handler_unblock(handler_id)

    3.2. Un Hola Mundo Mejorado

    1 #!/usr/bin/env python23 # Ejemplo helloworld2.py45 import pygtk6 pygtk.require(2.0)7 import gtk89 class HelloWorld2:

    1011 # La retrollamada mejorada. Los datos que se pasan a esta funcin12 # se imprimen por la salida estndar.13 def callback(self, widget, data):14 print "Hello again - %s was pressed" % data1516 # otra retrollamada17 def delete_event(self, widget, event, data=None):18 gtk.main_quit()19 return gtk.FALSE2021 def __init__(self):

    15

  • CAPTULO 3. AVANZANDO 3.2. UN HOLAMUNDOMEJORADO

    22 # Creamos una ventana23 self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)2425 # Esta llamada establece el ttulo de la26 # ventana como "Hello Buttons!"27 self.window.set_title("Hello Buttons!")2829 # Aqu establecemos un manejador para delete_event que30 # sale inmediatamente de GTK+.31 self.window.connect("delete_event", self.delete_event)3233 # Establece el grosor del borde de la ventana34 self.window.set_border_width(10)3536 # Creamos una caja en la que empaquetar los controles. Esto se

    describe detalladamente37 # en la seccin de "empaquetado". La caja no es visible en

    realidad sino que simplemente38 # facilita la organizacin de los controles.39 self.box1 = gtk.HBox(gtk.FALSE, 0)4041 # Introducimos la caja en la ventana principal42 self.window.add(self.box1)4344 # Crea un nuevo botn con la etiqueta "Button 1".45 self.button1 = gtk.Button("Button 1")4647 # Ahora, cuando se pulsa el botn, llamamos al mtodo "callback"48 # con un puntero a "button 1" como argumento49 self.button1.connect("clicked", self.callback, "button 1")5051 # En vez de usar add(), empaquetamos este botn en la caja

    visible52 # que ha sido introducida en la ventana.53 self.box1.pack_start(self.button1, gtk.TRUE, gtk.TRUE, 0)5455 # Hay que recordar siempre este paso, que indica a GTK+ que la

    preparacin del56 # botn ha terminado y que ya es posible mostrarlo.57 self.button1.show()5859 # Seguimos los mismos pasos para crear el segundo botn60 self.button2 = gtk.Button("Button 2")6162 # Llamamos la misma retrollamada pero con un argumento diferente,63 # haciendo referencia a "button 2" esta vez.64 self.button2.connect("clicked", self.callback, "button 2")6566 self.box1.pack_start(self.button2, gtk.TRUE, gtk.TRUE, 0)6768 # El orden en que mostramos los botones no es muy importante,

    pero es recomendable69 # mostrar la ventana en ltimo lugar, puesto que as aparece todo

    de una vez.70 self.button2.show()71 self.box1.show()72 self.window.show()7374 def main():75 gtk.main()7677 if __name__ == "__main__":78 hello = HelloWorld2()79 main()

    16

  • CAPTULO 3. AVANZANDO 3.2. UN HOLAMUNDOMEJORADO

    Al ejecutar helloworld2.py se genera la ventana de la Figura 3.1.

    Figura 3.1 Ejemplo mejorado de Hola Mundo

    Esta vez se puede ver que no hay forma fcil de salir del programa, y resulta necesario usar el gestorde ventanas o la lnea de comandos para eliminarlo. Un buen ejercicio para el lector sera insertar untercer botn "Salir" que cerrara el programa. Sera interesante jugar con las opciones de pack_start() altiempo que se lee la siguiente seccin, as como probar a cambiar de tamao la ventana y observar qusucede.

    Como nota, hay que mencionar otra constante til para gtk.Window() - WINDOW_DIALOG. Este tipode ventana interacta de forma distinta con el gestor de ventanas y debe usarse en ventanas de usotransitorio.

    A continuacin se describen en orden las pequeas diferencias del cdigo respecto a la versin inicialdel programa "Hola Mundo":

    Como ya se ha dicho, no existe manejador del evento "destroy" en esta versin mejorada de "HolaMundo".

    Las lneas 13-14 definen un mtodo de retrollamada similar a la retrollamada hello() del ejemploinicial. La diferencia reside en que ahora la retrollamada imprime un mensaje que incluye los datos quese le suministran.

    La lnea 27 pone ttulo a la barra de ttulo de la ventana (vase la Figura 3.1).La lnea 39 crea una caja horizontal (gtk.HBox) que almacena los dos botones que se crean en las

    lneas 45 y 60. La lnea 42 aade la caja horizontal al contenedor de la ventana.Las lneas 49 y 64 conectan el mtodo callback() a la seal "clicked" de los botones. Y cada botn

    establece una cadena diferente que se pasa al mtodo callback() al ser invocado.Las lneas 53 y 66 empaquetan los botones en la caja horizontal. Y, finalmente, las lneas 57 y 70

    indican a GTK+ que muestre los botones.Las lneas 71-72 piden finalmente a GTK+ que muestre la caja y la ventana.

    17

  • Captulo 4

    Empaquetado de Controles

    Normalmente, cuando se crea un programa, se desea poner ms de un control en la ventana. Nuestroprimer ejemplo "Hola Mundo" usaba un nico control para poder llamar simplemente al mtodo ad-d() de la clase gtk.Container para "empaquetar" el control en la ventana. Sin embargo, en cuanto sequiera poner ms de un control en una ventana, cmo se determina la posicin en la que se sita elcontrol?. Aqu es donde el "empaquetado" de controles entra en juego.

    4.1. Teora de Cajas Empaquetadoras

    La mayora del empaquetado se realiza utilizando cajas. stas son contenedores invisibles de con-troles y son de dos tipos: cajas horizontales y cajas verticales. En el primer tipo los los objetos se insertanhorizontalmente, de izquierda a derecha o de derecha a izquierda, en funcin de la llamada que se use;mientras que en el segundo tipo, las cajas verticales, los controles se empaquetan de arriba a abajo oviceversa. Es posible utilizar combinaciones de cajas insertadas en otras cajas y obtener cualquier efectoque se desee.

    Para crear una nueva caja horizontal se usa la llamada gtk.HBox(), y con cajas verticales gtk-.VBox() . Los mtodos pack_start() y pack_end() se utilizan para colocar los objetos dentro de estoscontenedores. El primer mtodo, pack_start(), inserta los objetos yendo de arriba hacia abajo en unacaja vertical, y de izquierda a derecha en una caja horizontal. El mtodo pack_end() muestra el compor-tamiento opuesto, empaqueta de abajo hacia arriba en una caja vertical, y de derecha a izquierda en unacaja horizontal. Con estos mtodos se pueden alinear a la derecha o a la izquierda los controles, de talforma que se consiga el efecto buscado. A lo largo de los ejemplos de este tutorial se usar fundamental-mente el mtodo pack_start(). Un objeto puede ser adems bien otro contenedor o bien un control. Dehecho, muchos controles son en realidad tambin contenedores, como ocurre con los botones, aunquenormalmente se use slo una etiqueta en su interior.

    Con las llamadas anteriores se indica a GTK+ cmo ha de situar los controles y as es capaz decambiar su tamao y otras propiedades interesantes de forma automtica. Y, como es de esperar, dichomtodo proporciona adems gran flexibilidad a la hora de situar y crear controles.

    4.2. Las Cajas en detalle

    A causa de esta flexibilidad, el empaquetado de cajas puede resultar confuso al principio, dado queadmite muchas opciones cuyo funcionamiento conjunto no resulta obvio. Sin embargo, existen bsica-mente cinco estilos. La Figura 4.1 muestra el resultado de la ejecucin del programa packbox.py con unargumento de 1:

    19

  • CAPTULO 4. EMPAQUETADO DE . . . 4.2. LAS CAJAS EN DETALLE

    Figura 4.1 Empaquetado: Cinco variaciones

    Cada lnea contiene una caja horizontal (hbox) con varios botones. La llamada a pack es una copiade la llamada a pack en cada uno de los botones de la Hbox. Cada botn se empaqueta en la hbox de lamisma manera (con los mismos argumentos al mtodo pack_start() ).

    Este es un ejemplo del mtodo pack_start():

    box.pack_start(child, expand, fill, padding)

    box es la caja donde se empaqueta el objeto. El primer argumento, child, es el objeto que se va aempaquetar. Por ahora los objetos sern botones, con lo que estaramos empaquetando botones dentrode cajas.

    El argumento expand de pack_start() y pack_end() controla si los controles se disponen de formaque ocupen todo el espacio extra de la caja y, de esta manera, sta se expande hasta ocupar todo el reareservada para ella (TRUE); o si se encoge para ocupar el espacio justo de los controles (FALSE). Ponerexpand a FALSE permite justificar a la derecha y a la izquierda los controles. Si no, se expandirn parallenar la caja, y el mismo efecto podra obtenerse usando slo o pack_start() o pack_end().

    El argumento fill controla si el espacio extra se utiliza en los propios objetos (TRUE) o como espacioextra en la caja alrededor de los objetos (FALSE). Slo tiene efecto si el argumento expand tambin esTRUE.

    Python permite definir un mtodo o funcin con valores de argumento predeterminados y argu-mentos con nombre. A lo largo de este tutorial se ver la definicin de las funciones y mtodos convalores predeterminados y argumentos con nombre cuando sean de aplicacin. Por ejemplo, el mtodopack_start se define as:

    box.pack_start(child, expand=gtk.TRUE, fill=gtk.TRUE, padding=0)

    box.pack_end(child, expand=gtk.TRUE, fill=gtk.TRUE, padding=0)

    child, expand, fill y padding son palabras clave (argumentos con nombre). Los argumentos expa-nd, fill y padding tienen los valores predeterminados (o "por defecto") mostrados arriba. El argumentochild debe especificarse obligatoriamente al no tener un valor predeterminado.

    Las funciones que nos permiten crear una caja nueva son:

    hbox = gtk.HBox(homogeneous=gtk.FALSE, spacing=0)

    vbox = gtk.VBox(homogeneous=gtk.FALSE, spacing=0)

    20

  • CAPTULO 4. EMPAQUETADO DE . . . 4.3. PROGRAMA DE EJEMPLO DE . . .

    El argumento homogeneous de gtk.HBox() y gtk.VBox() controla si cada objeto de la caja tiene elmismo tamao (por ejemplo, el mismo ancho en una hbox, o la misma altura en una vbox). Si se usa,las rutinas de empaquetado funcionan basicamente como si el argumento expand estuviera siempreactivado.

    Qu diferencia existe entre spacing (se fija al crear la caja) y padding (se determina al empaquetarlos elementos)? El spacing se aade entre objetos, y el padding se aade a cada lado de un objeto. LaFigura 4.2 ilustra la diferencia, pasando un argumento de 2 a packbox.py :

    Figura 4.2 Empaquetado con Spacing y Padding

    La Figura 4.3 ilustra el uso del mtodo pack_end() (pasa un argumento de 3 a packbox.py). La eti-queta "end" se empaqueta con el mtodo pack_end(). Se mantendr en el borde derecho de la ventanacuando sta se redimensione.

    Figura 4.3 Empaquetado con pack_end()

    4.3. Programa de Ejemplo de Empaquetado

    Aqu est el cdigo usado para crear la imagen anterior. Est profusamente comentado, as que noresultar complicado seguirlo. Es recomendable su ejecucin y jugar posteriormente con l.

    1 #!/usr/bin/env python23 # ejemplo packbox.py45 import pygtk6 pygtk.require(2.0)7 import gtk

    21

  • CAPTULO 4. EMPAQUETADO DE . . . 4.3. PROGRAMA DE EJEMPLO DE . . .

    8 import sys, string910 # Funcin auxiliar que crea una nueva HBox llena de botones con etiqueta.

    Los argumentos11 # de las variables en las que tenemos inters se pasan a esta funcin. No

    mostramos la12 # caja pero s todo lo que contiene.1314 def make_box(homogeneous, spacing, expand, fill, padding):1516 # Creamos una nueva HBox con los parmetros homogeneous17 # y spacing adecuados.18 box = gtk.HBox(homogeneous, spacing)1920 # Creamos una serie de botones con los parmetros adecuados21 button = gtk.Button("box.pack")22 box.pack_start(button, expand, fill, padding)23 button.show()2425 button = gtk.Button("(button,")26 box.pack_start(button, expand, fill, padding)27 button.show()2829 # Creamos un botn con una etiqueta que depende del valor de30 # expand.31 if expand == gtk.TRUE:32 button = gtk.Button("TRUE,")33 else:34 button = gtk.Button("FALSE,")3536 box.pack_start(button, expand, fill, padding)37 button.show()3839 # Aqu hacemos lo mismo que en la creacin del botn de "expand"40 # anterior, pero usa la forma abreviada.41 button = gtk.Button(("FALSE,", "TRUE,")[fill==gtk.TRUE])42 box.pack_start(button, expand, fill, padding)43 button.show()4445 padstr = "%d)" % padding4647 button = gtk.Button(padstr)48 box.pack_start(button, expand, fill, padding)49 button.show()50 return box5152 class PackBox1:53 def delete_event(self, widget, event, data=None):54 gtk.main_quit()55 return gtk.FALSE5657 def __init__(self, which):5859 # Creamos nuestra ventana60 self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)6162 # Siempre debemos recordar la conexin de la seal delete_event63 # a la ventana principal. Esto es muy importante de cara a un

    comportamiento64 # intuitivo adecuado65 self.window.connect("delete_event", self.delete_event)66 self.window.set_border_width(10)6768 # Creamos una caja vertical (vbox) en la que empaquetar las cajas

    22

  • CAPTULO 4. EMPAQUETADO DE . . . 4.3. PROGRAMA DE EJEMPLO DE . . .

    horizontales.69 # Esto nos permite apilar las cajas horizontales llenas de botones70 # una encima de otra en esta vbox.71 box1 = gtk.VBox(gtk.FALSE, 0)7273 # qu ejemplo mostramos. stos se corresponden a las imgenes

    anteriores.74 if which == 1:75 # creamos una etiqueta nueva.76 label = gtk.Label("HBox(FALSE, 0)")7778 # Alineamos la etiqueta al lado izquierdo. Comentaremos este y

    otros79 # mtodos en la seccin sobre Atributos de los Controles.80 label.set_alignment(0, 0)8182 # Empaquetamos la etiqueta en la caja vertical (vbox box1).

    Recurdese que83 # los controles que se aaden a una caja vertical se apilan uno

    encima del otro84 # en orden.85 box1.pack_start(label, gtk.FALSE, gtk.FALSE, 0)8687 # Mostramos la etiqueta88 label.show()8990 # Llamamos a nuestra funcin de crear caja - homogeneous =

    FALSE, spacing = 0,91 # expand = FALSE, fill = FALSE, padding = 092 box2 = make_box(gtk.FALSE, 0, gtk.FALSE, gtk.FALSE, 0)93 box1.pack_start(box2, gtk.FALSE, gtk.FALSE, 0)94 box2.show()9596 # Llamamos a nuestra funcin de crear caja - homogeneous =

    FALSE, spacing = 0,97 # expand = TRUE, fill = FALSE, padding = 098 box2 = make_box(gtk.FALSE, 0, gtk.TRUE, gtk.FALSE, 0)99 box1.pack_start(box2, gtk.FALSE, gtk.FALSE, 0)

    100 box2.show()101102 # Los argumentos son: homogeneous, spacing, expand, fill,

    padding103 box2 = make_box(gtk.FALSE, 0, gtk.TRUE, gtk.TRUE, 0)104 box1.pack_start(box2, gtk.FALSE, gtk.FALSE, 0)105 box2.show()106107 # Crea un separador, que veremos qu hacen ms adelante,108 # aunque son muy simples.109 separator = gtk.HSeparator()110111 # Empaquetamos el separador en la vbox. Recurdese que

    empaquetamos todos estos112 # controles en una vbox, por lo que se apilarn113 # verticalmente.114 box1.pack_start(separator, gtk.FALSE, gtk.TRUE, 5)115 separator.show()116117 # Creamos otra etiqueta y la mostramos.118 label = gtk.Label("HBox(TRUE, 0)")119 label.set_alignment(0, 0)120 box1.pack_start(label, gtk.FALSE, gtk.FALSE, 0)121 label.show()122123 # Los argumentos son: homogeneous, spacing, expand, fill,

    23

  • CAPTULO 4. EMPAQUETADO DE . . . 4.3. PROGRAMA DE EJEMPLO DE . . .

    padding124 box2 = make_box(gtk.TRUE, 0, gtk.TRUE, gtk.FALSE, 0)125 box1.pack_start(box2, gtk.FALSE, gtk.FALSE, 0)126 box2.show()127128 # Los argumentos son: homogeneous, spacing, expand, fill,

    padding129 box2 = make_box(gtk.TRUE, 0, gtk.TRUE, gtk.TRUE, 0)130 box1.pack_start(box2, gtk.FALSE, gtk.FALSE, 0)131 box2.show()132133 # Otro separador.134 separator = gtk.HSeparator()135 # Los ltimos 3 argumentos de pack_start son:136 # expand, fill, padding.137 box1.pack_start(separator, gtk.FALSE, gtk.TRUE, 5)138 separator.show()139 elif which == 2:140 # Creamos una etiqueta nueva, recordando que box1 es una vbox

    creada141 # cerca del comienzo de __init__()142 label = gtk.Label("HBox(FALSE, 10)")143 label.set_alignment( 0, 0)144 box1.pack_start(label, gtk.FALSE, gtk.FALSE, 0)145 label.show()146147 # Los argumentos son: homogeneous, spacing, expand, fill,

    padding148 box2 = make_box(gtk.FALSE, 10, gtk.TRUE, gtk.FALSE, 0)149 box1.pack_start(box2, gtk.FALSE, gtk.FALSE, 0)150 box2.show()151152 # Los argumentos son: homogeneous, spacing, expand, fill,

    padding153 box2 = make_box(gtk.FALSE, 10, gtk.TRUE, gtk.TRUE, 0)154 box1.pack_start(box2, gtk.FALSE, gtk.FALSE, 0)155 box2.show()156157 separator = gtk.HSeparator()158 # Los ltimos 3 argumentos de pack_start son:159 # expand, fill, padding.160 box1.pack_start(separator, gtk.FALSE, gtk.TRUE, 5)161 separator.show()162163 label = gtk.Label("HBox(FALSE, 0)")164 label.set_alignment(0, 0)165 box1.pack_start(label, gtk.FALSE, gtk.FALSE, 0)166 label.show()167168 # Los argumentos son: homogeneous, spacing, expand, fill,

    padding169 box2 = make_box(gtk.FALSE, 0, gtk.TRUE, gtk.FALSE, 10)170 box1.pack_start(box2, gtk.FALSE, gtk.FALSE, 0)171 box2.show()172173 # Los argumentos son: homogeneous, spacing, expand, fill,

    padding174 box2 = make_box(gtk.FALSE, 0, gtk.TRUE, gtk.TRUE, 10)175 box1.pack_start(box2, gtk.FALSE, gtk.FALSE, 0)176 box2.show()177178 separator = gtk.HSeparator()179 # Los ltimos 3 argumentos de pack_start son:180 # expand, fill, padding.

    24

  • CAPTULO 4. EMPAQUETADO DE . . . 4.3. PROGRAMA DE EJEMPLO DE . . .

    181 box1.pack_start(separator, gtk.FALSE, gtk.TRUE, 5)182 separator.show()183184 elif which == 3:185186 # Esto ilustra la posibilidad de usar pack_end() para187 # alinear los controles a la derecha. Primero creamos una caja

    nueva, como antes.188 box2 = make_box(gtk.FALSE, 0, gtk.FALSE, gtk.FALSE, 0)189190 # Creamos la etiqueta que pondremos al final.191 label = gtk.Label("end")192 # La empaquetamos con pack_end(), por lo que se pone en el

    extremo derecho193 # de la hbox creada en la llamada a make_box().194 box2.pack_end(label, gtk.FALSE, gtk.FALSE, 0)195 # Mostramos la etiqueta.196 label.show()197198 # Empaquetamos la box2 en box1199 box1.pack_start(box2, gtk.FALSE, gtk.FALSE, 0)200 box2.show()201202 # Un separador para la parte de abajo.203 separator = gtk.HSeparator()204205 # Esto establece explcitamente el ancho del separador a 400

    pxeles y 5206 # pxeles de alto. As la hbox que creamos tambin tendra 400207 # pxeles de ancho, y la etiqueta "end" estar separada de las

    otras208 # de la hbox. En otro caso, todos los controles de la209 # hbox estaran empaquetados lo ms juntos posible.210 separator.set_size_request(400, 5)211 # empaquetamos el separador en la vbox (box1) creada cerca del

    principio212 # de __init__()213 box1.pack_start(separator, gtk.FALSE, gtk.TRUE, 5)214 separator.show()215216 # Creamos otra hbox nueva. Recordemos que podramos usar cuantas

    queramos!217 quitbox = gtk.HBox(gtk.FALSE, 0)218219 # Nuestro botn de salida.220 button = gtk.Button("Quit")221222 # Configuramos la seal que finalice el programa al pulsar el botn223 button.connect("clicked", lambda w: gtk.main_quit())224 # Empaquetamos el botn en la quitbox.225 # Los 3 ltimos argumentos de pack_start son:226 # expand, fill, padding.227 quitbox.pack_start(button, gtk.TRUE, gtk.FALSE, 0)228 # empaquetamos la quitbox en la vbox (box1)229 box1.pack_start(quitbox, gtk.FALSE, gtk.FALSE, 0)230231 # Empaquetamos la vbox (box1), que ahora contiene todos los

    controles,232 # en la ventana principal.233 self.window.add(box1)234235 # Y mostramos todo lo que queda236 button.show()237 quitbox.show()

    25

  • CAPTULO 4. EMPAQUETADO DE . . . 4.4. USO DE TABLAS PARA EL EMPAQUETADO

    238239 box1.show()240 # Mostrando la ventana al final de forma que todo aparezca de una

    vez.241 self.window.show()242243 def main():244 # y, naturalmente, el bucle de eventos principal.245 gtk.main()246 # El control se devuelve a este punto cuando se lla