Tabla de contenido
GTK, ¿qué es?:
GTK es un acrónimo para GIMP ToolKit, es al día de hoy una de las plataformas para creación de Entornos Gráficos más populares en sistemas Linux/Unix. GTK nace como librería de soporte para el proyecto GIMP (GNU Image Manipulation Program) intentando reemplazar a las viejas librerías de imágenes de el sistema X de ventanas.
Después de grandes avances y continuas mejoras, se gana un lugar como proyecto independiente bajo el nombre de GTK+.
GTK+ se ha diseñado para permitir programar con lenguajes como C, C++, C#, Java, Ruby, Perl, PHP o Python.
Los entornos de escritorio no son necesarios para ejecutar los programas GTK+. Si las bibliotecas que requiere el programa están instaladas, un programa GTK+ puede ser ejecutado por encima de otros entornos basadas en X11 como KDE o cualquier otro entorno, lo que incluye Mac OS X. GTK+ también puede ejecutarse en Microsoft Windows, es utilizado por algunas aplicaciones populares multiplataforma como Pidgin y GIMP.
GTK+ se ha construido en base a tres librerías: GDK (GIMP Drawing Kit) para interactuar con el
sistema gráfico, gdk-pixbuf para manipular imágenes y Glib para integración con el Sistema Operativo(SO).
GTK+ es la librería gráfica (toolkit) sobre la que se sustenta todo el interfaz gráfico de GNOME. Es una librería que contiene todo lo necesario para el desarrollo de interfaces gráficas, permitiendo la posibilidad de crear todo tipo de widgets, desde los más básicos, como; botones, etiquetas, cajas de texto, hasta cosas más complejas como; selectores de ficheros, colores, fuentes, cajas de texto multilínea con soporte para todo tipo de efectos sobre el texto, etc.
SEPARACIÓN DE CAPAS:
Las librerías GTK+ se basan en la separación de capas de sus componentes. Este esquema permite que cada capa se especialice en cumplir con un determinado trabajo. De esta forma, el avance del hardware y de los conceptos de usabilidad son responsabilidad de la capa que se encarga de ellos y no de toda la plataforma. Esto dio pié al avance continuo e independiente de cada capa y la posibilidad de intercambiar capas para utilizar GTK+ en diferentes plataformas. Las diferentes capas de GTK + son;
Xlib – Da el acceso directo al protocolo del servidor X de ventanas (X windows system) de manera simplificada. Es una interfaz de muy bajo nivel.
GTK – Biblioteca la cual realmente contiene los objetos y funciones para crear la interfaz de usuario. Maneja widgets como; ventanas, botones, menús, etiquetas, deslizadores, pestañas, etc.
Glib – Así como GTK surge como librería interna del GIMP, GLib tiene sus orígenes como librería interna de GTK. Posee utilidades y estructuras de datos no orientadas al manejo gráfico: strings, fechas, internacionalización, listas, estructuras de hash, caches, manejo de memoria, etc.
Gobject – Provee programación soporte para POO en C. Surge como proyecto interno a Glib del cual aún no se separó por completo.
Gdk – Acrónimo para GIMP DrawingKit, nace junto con GTK como capa intermedia entre éste y Xlib. Permite conceptualizar el acceso a la interfaz gráfica independientemente de la utilización de un entorno X o de los recursos de otro sistema operativo. Tanto es así que el intercambio de esta capa permite a GTK funcionar en entornos MS Windows sin mayores cambios.
Cairo – Pango – Proveen soporte para la manipulación vectorizada de gráficos (Cairo) y escritura de texto de alta calidad (Pango).
La librería GTK
GTK es una librería para crear interfaces gráficas. Tiene licencia LGPL, por lo cual se pueden desarrollar todo tipo de aplicaciones: código abierto, código cerrado, software libre, etc.
Los componentes de GTK+ se interrelacionan de la siguiente manera:
GLIB es la base del proyecto GTK+ y GNOME. GLIB provee las estructuras de datos en el lenguaje C. Contiene la infraestructura necesaria para construir envoltorios e interfaces para tales funciones como un bucle de ejecución de eventos, hilos, carga dinámica de módulos y un sistema de objetos.
GObject es la parte de Glib que implementa las características de lenguajes orientados a objetos que no están disponibles intrínsecamente en el lenguaje C. De esta manera GTK+ puede ser una caja de herramientas orientada a objetos sin tener que implementarse en C++ u otro lenguaje.
GDK (GIMP DrawingKit) interactúa con las primitivas gráficas de cada SO y las prepara para su uso con GTK+. En los sistemas UNIX soportados como Linux y Solaris, GDK interactúa con el sistema X-Window[1], mientras que en sistemas WindowsTM lo hará con GDI[2] y en MacOS XTM con QuartzTM[3]. El programador de aplicaciones no notará esto y, salvo raras excepciones, un programa escrito para GTK+ en Linux, por ejemplo, puede compilarse en Windows sin mayor modificación.
GdkPixbuf contiene convenientes rutinas para el manejo de imágenes(png, gif, jpeg, etc), tales como abrir y guardar, trabajar con mapas de imágenes en memoria, escalado y animaciones entre otras características.
Pango es un entorno de trabajo para el procesamiento y despliegue de texto internacional utilizando UTF8 como código base[4]; está integrado por completo en GTK+ y permite desplegar caracteres en distintos alfabetos y estilos de escritura (occidental, cirílico, árabe, chino, etc), texto bidireccional y con atributos como color, tamaño y estilo o rotación.
ATK proporciona un conjunto de interfaces de accesibilidad. Si uno soporta interfaces ATK en un programa, tendremos la posibilidad de utilizar diferentes herramientas como magnificadores de pantalla, texto a diálogo o diferentes métodos de entrada para personas con capacidades diferentes.
Widgets, ¿qué son?:
Son controles que nos proporcionan GTK. Dentro se encapsulan ciertos comportamientos y estados que proveen de abstracción para determinados conceptos generales de Entornos Gráficos. Los Widgets son codificados de tal forma que ocultan el manejo gráfico de bajo nivel y nos permiten utilizar un interfaz mucho más sencilla. Algunos Widgets de GTK son; GtkButton, GtkEntry, GtkLabel, GtkWindow, GtkRuler, GtkTooltip, etc …
Los Widgets de GTK poseen una estructura de clases jerárquicas. Todo elementos hereda de GtkWidget y este a su vez hereda de GtkObject. Cada hijo agrega funcionalidades y estados a su padre. Cada nueva rama en la jerarquía muestra una separación de comportamiento con respecto a sus ramas hermanas.
La librería GTK+ sigue el modelo de programación orientado a objetos. La jerarquía de objetos comienza en GObject de la librería Glib del que hereda GtkObject. Todos los widgets heredan de la clase de objetos GtkWidget, que a su vez hereda directamente de GtkObject. La clase GtkWidget contiene las propiedades comunes a todos los widgets; cada widget particular añade sus propias propiedades.
Un esquema reducido de la jerarquía de algunos widgets de GTK es el siguiente:
Gobject | GtkObject +GtkWidget | +GtkMisc | | +GtkLabel | | `GtkImage | +GtkContainer | | +GtkBin | | | +GtkFrame | | | +GtkButton | | | | +GtkToggleButton | | | | | `GtkCheckButton | | | | | `GtkRadioButton | | | | `GtkOptionMenu | | | +GtkItem | | | | +GtkMenuItem | | | +GtkWindow | | | | +GtkDialog | | | | | +GtkColorSelectionDialog | | | | | +GtkFileSelection | | | | | +GtkFontSelectionDialog | | | | | +GtkInputDialog | | | | | `GtkMessageDialog | | | +GtkScrolledWindow | | +GtkTable | | +GtkTextView | | +GtkToolbar | | `GtkTreeView | +GtkCalendar | +GtkDrawingArea | +GtkEditable | | +GtkEntry | | `GtkSpinButton | +GtkRuler | +GtkRange | +GtkSeparator +GtkTooltips |
Los widgets, como cualquier clase, poseen; constructores, destructores, métodos y atributos
definidos. Un ejemplo de utilización:
GtkWidget* button = gtk_button_new_with_label("botón");
gtk_button_set_alignment(GTK_BUTTON(button), 0.0, 1.0);
gtk_widget_destroy(button);
Nomenclatura en GTK:
Considerando que el software Libre como GTK o GNOME son proyectos enormes que no pueden ser manejados por un grupo reducido de personas, ofrecer una nomenclatura general consistente es de vital importancia para poder coordinar los a los miles de programadores alrededor del mundo que trabajan en estos proyectos.
Un pequeño resumen de la nomenclatura utilizada por GTK podría ser:
Siempre que sea posible, en GTK se debe evitar el uso de variables globales. Esto es importante aún más para librerías, ya que las variables globales dentro de los módulos se exportan junto a las funciones (métodos si consideramos a una librería como un objeto).
Todos estos símbolos se integran en el espacio global de nombres de la aplicación que llama a la librería (conocida como Global Namespace).
Una variable global de una librería cuyo nombre haya sido asignado de manera descuidada puede causar conflictos con otra variable con el mismo nombre que se esté usando en una parte del código que utiliza la librería.
Los nombres de las funciones deberán tener la forma modulo_submodulo_operacion().
Esta nomenclatura evita el choque de símbolos o nombres entre diferentes módulos de las librerías.
En los símbolos (funciones y variables), es aconsejable usar nombres descriptivos: en lugar de usar cntusr() deberemos usar contar_usuarios_activos(). Esto hace que el código fuente sea fácil de usar y casi auto-documentado facilitando así las tareas posteriores.
Los nombres de funciones deben estar en minúsculas y usarán un guión bajo para separar palabras, por ejemplo:
g_string_destroy(),
gtk_window_new(),
abrir_puerto().
Las macros y enumeraciones deben escribirse en letras mayúsculas, utilizando guiones bajos para separar palabras, por ejemplo: TRUE o G_DIR_SEPARATOR .
Tipos de datos, objetos y nombres de estructuras son una mezcla entre mayúsculas y minúsculas, por ejemplo: Gslist, GtkWidget.
El uso de guión bajo para separar palabras hace que el código fuente parezca menos apretado siendo así más fácil de editar ya que se pueden utilizar de mejor manera los comandos de navegación por palabras de los editores de texto haciendo que naveguemos más rápidamente por el código.
A la hora de escribir una librería se hace común compartir símbolos (nombres de variables o funciones), entre los diversos componentes de la librería. pero no se desea que estos símbolos estén disponibles para los usuarios de la librería. En este caso, se puede anteponer un guión bajo al nombre de la función o variable mientras éste sigue la nomenclatura modulo/submódulo descrita anteriormente. Por ejemplo: _modulo_objeto_algunmetodo().
Teoría de señales y retrollamadas
GTK es una librería dirigida por eventos. Desde el punto de vista del programador esto significa que se quedará en el bucle principal de ejecución ( gtk_main() ), hasta que algún evento o señal ocurra y el control se pase a la función apropiada.
Las señales son el medio por el cual GTK informa a las aplicaciones de los acontecimientos producidos en el interfaz gráfico o dentro de los objetos que componen el programa.
Las señales son importantes dentro de las aplicaciones con interfaz gráfica de usuario ya que el programa debe responder a las acciones que el usuario ejecute que por naturaleza son asíncronas y no se pueden predecir o prever.
Si el usuario mueve el ratón, presiona un botón, escribe un texto o cierra una ventana, una función retro-llamada se ejecuta y se realiza la acción requerida por el usuario, como puede ser guardar un archivo.
De alguna forma, antes de cerrar una aplicación se hace necesario llamar a rutinas de limpieza, guardar el trabajo del usuario o simplemente desplegar un diálogo que pregunte si realmente desea cerrar la ventana.
Cuando deseamos atender a la escucha de una señal o retro-llamada, se asocia un widget y una función en C. Así, también se puede asociar retro-llamadas a más de un widget ahorrando código que deba escribirse.
Callbacks
Se trata de funciones que se pueden pasar como argumento para otro bloque de código. Un callback es cualquier conjunto de instrucciones ejecutable desde otro punto del código mediante su invocación.
En C, los callbacks no son más que punteros a funciones, en este caso necesitarán información acerca del evento que están manejando e incluso del widget que lo disparó.
Como ejemplo , las funciones callbacks suelen tener la siguiente firma, recibiendo al widget que generó el evento y la información de contexto que se indicó al registrar el callback:
void callback_func( GtkWidget *widget, gpointer callback_data );
Por supuesto, se podría optar por otro orden de argumentos:
void callback_func( gpointer callback_data, GtkWidget *widget);
Aunque no es tan común, esta opción también es utilizada).
Eventos
Son propios de la plataforma gráfica, estos son capturados por GDK (del inglés GIMP Drawing Kit, es una biblioteca de gráficos que actúa como un intermediario entre gráficos de bajo nivel y gráficos de alto nivel. ). Los eventos de este estilo incluyen información de bajo nivel relacionada con el manejo de los dispositivos físicos de estrada-salida (Button_press_event, key_press_event, scroll_event, expose_event) o bien funciones propias del manejo de los componentes gráficos básicos del entorno gráfico (destroy_event, delete_event, property_notify_event, etc …)
Existe un conjunto de eventos que reflejan como las X manejan los eventos. Se pueden asignar funciones de respuesta a esos eventos. Los eventos más conocidos son:
• event • button_press_event • button_release_event • motion_notify_event • delete_event • destroy_event • expose_event • key_press_event • key_release_event • enter_notify_event • leave_notify_event • configure_event • focus_in_event • focus_out_event | • map_event • unmap_event • property_notify_event • selection_clear_event • selection_request_event • selection_notify_event • proximity_in_event • proximity_out_event • drag_begin_event • drag_request_event • drag_end_event • drop_enter_event • drop_leave_event • drop_data_available_event • other_even |
Bucle de ejecución y eventos
En GTK se usa el modelo de programación por eventos. Este modelo consiste en la asociación de determinadas acciones (“eventos”) a determinadas operaciones (“funciones”). Estas acciones, o eventos, marcan un cambio de estado de determinado objeto, de forma en que la aplicación pueda ser informada de ello.
Los eventos en GTK se refieren a señales especificadas en la definición de las clases de los distintos widgets. Para que este sistema de señales funcione, se usa lo que se denomina el bucle de eventos, que no más que un bucle interno de GTK, en el que se van comprobando los estados de cada uno de los elementos de la aplicación, e informados. Este concepto es exactamente idéntico al bucle de ejecución contenido en la librería GLIB y no es más que una aplicación de dicho concepto para hacerlo funcionar en aplicaciones con interfaz gráfica. Este bucle de eventos GTK se traduce básicamente en dos funciones, que son:
– void gtk_main (void);
– void gtk_main_quit (void);
Estas dos funciones análogas a g_main_run y g_main_quit representan el interfaz que tienen las aplicaciones para usar el bucle de eventos. Como el caso de su equivalencia de Glib, gtk_main ejecuta el bucle de eventos. Esto significa que, cuando se haya realizado la llamada a gtk_main, se cede todo el control de la aplicación a GTK. Es decir, gtk_main_quit, que como su nombre indica, termina el bucle de eventos GTK.
OBJETOS GTK
Widgets contenedores
Uno de los conceptos fundamentales de Gtk son los contenedores. Un widget contenedor es aquel que es capaz de contener a otros widgets. Existen una gran cantidad de contenedores y GTK+ los utiliza para acomodar los widgets dentro de la interfaz gráfica de usuario..
Cuando se escribe una aplicación, normalmente se necesita colocar mas de un widget dentro de una ventana.
El diagrama de herencia de clase de GtkWindow es el que se puede ver en la imágen:
GtkWindow también puede contener otros widgets, pues desciende de la clase GtkContainer, eso significa que, a pesar de tener la capacidad de almacenar otros widgets por ser descendiente de GtkContainer, la clase GtkWindow sólo puede contener un sólo widget debido a su parentesco inmediato con GtkBin.
Al igual que GtkWidget, GtkContainer y GtkBin son clases abstractas. Eso quiere decir que no son instanciables y sólo sirven de plantillas para otros widgets. La clase GtkBin es muy simple y sólo contiene un método, por eso sus descendientes directos solo pueden contener un sólo widget.
Cajas
En el mundo de GTK una caja es un widget que organiza un grupo de objetos en un área rectangular: Si deseamos colocar varios de ellos en una sola ventana usaremos una caja y esta se puede insertar, a su vez, en la ventana.
La ventaja principal de usar cajas es la de despreocuparnos del lugar donde debemos dibujar cada uno de nuestros objetos gráficos, GTK toma se encarga por nosotros.
Existen dos tipos de cajas: GtkHBox y GtkVBox. Ambos descienden de la clase abstracta GtkBox y son invisibles.
Cuando se empaquetan widgets en una caja horizontal (GtkHBox) se acomodan horizontalmente de izquierda a derecha o viceversa y todos tienen la misma altura.
En una caja vertical (GtkVBox) los widgets se acomodan de arriba a abajo o viceversa y todos tienen el mismo ancho. También se puede usar una combinación de cajas dentro o al lado de otras cajas para crear el efecto deseado. GtkBox es una clase abstracta, y las clases derivadas (GtkHBox y GtkVBox) no contienen métodos de clase. Los constructores de clase son solamente para las cajas verticales u horizontales mientras que los métodos de clase son de GtkBox.
Tablas
Una tabla es una rejilla en donde se colocan widgets. Los widgets pueden ocupar los espacios que se especifiquen (1 o más celdas).
Como es común en GTK, un contenedor no tiene una representación gráfica pero afecta la posición y tamaño de los elementos que contiene. Cada widget se inserta dentro de la cuadrícula de la tabla.
Un widget hijo puede ocupar el espacio de una o más celdas de la siguiente línea o columna, o ambas. Las coordenadas de ese rectángulo definen de qué celda a qué celda ocupará un widget.
Etiquetas
GtkLabel es útil para desplegar cantidades moderadas de información en forma de texto el cual se puede alinear a la izquierda, derecha y de forma centrada.
La opción de lenguaje de marcado (similar a HTML) mejora la calidad y cantidad de información desplegada usando tipos de letra (itálica, negritas, subrayado) y colores.
Botones
GtkButton es un widget que emite una señal cuando es presionado. Un botón es a su vez un contenedor. Por lo general contiene una etiqueta, una imagen o ambas. GtkButton es punto de partida para la creación de otros tipos de botones.
GtkColorButton es un botón que al ser presionado muestra una ventana de selección de color y GtkFontButton mostrará una ventana de selección de tipo de fuente al ser presionado.
Cajas de texto
GtkEntry es un widget de entrada de texto. Este puede almacenar sólo una cantidad limitada de información debido a que sólo despliega una linea de texto. Si el texto que se introduce es más largo del que se puede mostrar, entonces el contenido de la caja de texto se irá desplazando de tal manera que se pueda visualizar lo que se está escribiendo.
Estas cajas disponen de la mayoría de los atajos del teclado más comunes en cualquier aplicación. Además también soporta arrastrar y soltar (drag & drop).
Con la integración de Pango como componente base de GTK, todos los objetos de texto de GTK tienen la posibilidad de desplegar textos en otros alfabetos diferentes y soportar métodos de escritura diferentes al nuestro.