Posts Tagged ‘GTK+’

Tutorial Gtk+2: Widgets, Signals y Callbacks (o “como funcionan las cosas”)

En esta sección del tutorial revisaremos la forma en la que puede interactuar el usuario con Gtk+ esto se logra principalmente con 3 herramientas en la mayoría de las interfaces gráficas:

1.-Widgets (dispositivo, artilugio), esto es toda herramienta con la que pueda interactuar el usario de forma directa o indirecta, ejemplos de widgets son: botones, campos de texto, listas, tablas etc.

2.-Signals (señales), toda muestra de que el usario ha utlilicado un widget utilizando algún dispositivo de entrada como es el teclado o el mouse, ejemplos de señales son: clicks, apretar alguna tecla, mover el puntero del ratón sobre algún área concreta etc.

3.-Callbacks (call back=”devolver llamada”), son las funciones que unen las señales y los widgets bajo un mismo contexto y realizan alguna acción en concreto, al dar “click” sobre el “boton abrir” se ejecuta una callback que abre el diálogo de selección de archivo, reciben el nombre de callbacks, ya que el sistema se encuentra en continuo monitoreo de las señales que podrían manifestarse mientras la ventana esta activa, y cuando detectan alguna las callbacks “devuelven la llamada” al sistema ejecutando la orden deseada.

Sin más preámbulos el código de esta sección:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#include  #include <gtk/gtk.h>
 
struct context{
   int i;
   GtkWidget* label;
}context;
 
static void aumenta( GtkWidget *widget,struct context* cntxt )
{
    cntxt->i++;
    const char* text=g_strdup_printf("#:%d",cntxt->i);
    gtk_label_set_text((GtkLabel*)cntxt->label,text);
}
 
static void destroy( GtkWidget *widget, gpointer   data )
{
    gtk_main_quit ();
}
 
int main( int   argc, char *argv[] )
{
    GtkWidget *window;
    GtkWidget *button;
    GtkWidget *box;
    struct context cntxt;
    cntxt.i=0;
 
    gtk_init (&argc, &argv);
 
    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
 
    g_signal_connect (G_OBJECT (window), "destroy",
		      G_CALLBACK (destroy), NULL);
 
    gtk_container_set_border_width (GTK_CONTAINER (window), 10);
 
    button = gtk_button_new_with_label ("¡Presioname!");
    cntxt.label= gtk_label_new("#:0");
    box=gtk_hbox_new(FALSE,0);
 
    g_signal_connect (G_OBJECT (button), "clicked",
		      G_CALLBACK (aumenta), &cntxt);
 
    gtk_container_add (GTK_CONTAINER (window), box);
    gtk_box_pack_start(GTK_BOX(box),button,TRUE,TRUE,0);
    gtk_box_pack_start(GTK_BOX(box),cntxt.label,TRUE,TRUE,0);
 
    gtk_widget_show (button);
    gtk_widget_show(box);
    gtk_widget_show (cntxt.label);
    gtk_widget_show (window);
 
    gtk_main ();
 
    return 0;
}

Linea por linea:

1
2
3
4
5
6
#include  <gtk/gtk.h>
 
struct context{
   int i;
   GtkWidget* label;
}context;

Analizemos el código, al comenzar incluimos nuestras librerias de gtk, despues viene una pequeña estructura que son los elementos a modificar mediante la callback.

8
9
10
11
12
13
static void aumenta( GtkWidget *widget,struct context* cntxt )
{
    cntxt->i++;
    const char* text=g_strdup_printf("#:%d",cntxt->i);
    gtk_label_set_text((GtkLabel*)cntxt->label,text);
}

Nuestra callback principal todas las callback tienen la siguiente estructura soyunacallback(GtkWidget* widget,gpointer data) donde el primer parametro es el widget que recibio la señal y el segundo es un puntero con los datos que queremos utilizar dentro de la callback, en este caso nuestra estructura.

8
9
10
11
static void destroy( GtkWidget *widget, gpointer   data )
{
    gtk_main_quit ();
}

Otra callback, esta realiza la tarea de terminar nuestro proceso en forma (al contrario de la sección anterior donde habia que hacerlo desde consola) y se ejecuta cuando la ventana recibe la señal “destroy” y que se pueda dar de distintas formas, como hacer click en la X de la esquina superior derecha (por si no la encuentran), o apretar la combinación de teclas alt-f4.

20
21
22
23
24
25
26
27
28
29
30
int main( int   argc, char *argv[] )
{
 GtkWidget *window;
 GtkWidget *button;
 GtkWidget *box;
 struct context cntxt;
 cntxt.i=0;
 
 gtk_init (&argc, &argv);
 
 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);

Inicio de nuestra funcion main, declaración de cuatro widgets y nuestra estructura e inicialización de la variable i y de window.

32
33
34
35
g_signal_connect (G_OBJECT (window), "destroy",
		      G_CALLBACK (destroy), NULL);
 
gtk_container_set_border_width (GTK_CONTAINER (window), 10);

Conexión de el Widget ventana, con la señal “destroy” y la callback homónima, el ultimo parametro como se verá mas adelante es el mismo “gpointer data” de la callback, la siguiente linea define el grosor del borde de la ventana.

37
38
39
 button = gtk_button_new_with_label ("¡Presioname!");
cntxt.label= gtk_label_new("#:0");
box=gtk_hbox_new(FALSE,0);

Inicialización de los widgets “button” y “label”, el ultimo de nuestra estructura, en la ultima linea se inicializa el Widget del tipo hbox, que nos permitira acomodar varios widgets dentro de nuestra ventana, tema que se explicará más ampliamente en la siguiente sección.

41
42
g_signal_connect (G_OBJECT (button), "clicked",
		      G_CALLBACK (aumenta), &cntxt);

Conexión del widget button con la señal “clicked” y la callback aumenta, aqui podemos ver como el úlitmo parametro es un apuntador a nuestra estructura.

44
45
46
    gtk_container_add (GTK_CONTAINER (window), box);
    gtk_box_pack_start(GTK_BOX(box),button,TRUE,TRUE,0);
    gtk_box_pack_start(GTK_BOX(box),cntxt.label,TRUE,TRUE,0);

Aqui agregamos el widget del tipo caja al contenedor ventana, y en lugar de utilizar la función gtk_container_add, se utiliza la funcion gtk_box_pack_start, se especificarán los parámetros de esta función en la siguiente sección dedicada a contenedores.

48
49
50
51
52
53
54
55
56
    gtk_widget_show (button);
    gtk_widget_show(box);
    gtk_widget_show (cntxt.label);
    gtk_widget_show (window);
 
    gtk_main ();
 
    return 0;
}

Se muestran todos nuestros widgets y se da comienzo a la función principal, la cual permite el “escuchar” si alguna señal ha sido emitida y ejecuta la callback adecuada según el caso.

Tutorial Gtk+2: Hola Mundo

Una vez que tenemos instalado Gtk+ en nuestra computadora, nuestro primer programa sera el famoso “¡Hola Mundo!” , este consiste en una simple ventana con una etiqueta, el código de nuestro holamundo.c seria este:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <gtk/gtk.h>
 
int main(int argc,char *argv[]){
 
  GtkWidget * window;
  GtkWidget * label;
 
  gtk_init (&argc,&argv);
 
  label=gtk_label_new("Hola Mundo");
  window=gtk_window_new (GTK_WINDOW_TOPLEVEL);
 
  gtk_container_add(GTK_CONTAINER(window),label);
 
  gtk_widget_show (label);
  gtk_widget_show (window);
 
  gtk_main();
 
  return 0;
}

Revisemos el código liena por linea:

1
#include <gtk/gtk.h>

Esta linea incluye todas las librerias que usaremos en esto y cualquier programa de Gtk+, por lo cual la usaremos en todos los programas que realizemos.

3
int main(int argc,char *argv[]){

Nuestra funcion main, la cual nos permite ejecutar el programa, como cualquier otro programa en c.

5
6
  GtkWidget * window;
  GtkWidget * label;

Estas lineas declaran nuestros apuntadores a datos del tipo GtkWidget, para declara una ventana y una etiqueta respectivamente.

8
  gtk_init (&argc,&argv);

La inicializacion de Gtk+ que sera llamada en todos nuestros programas, principalmente realiza la preparación para el uso de Gtk+ preparando, entre otras cosas, las señales estándar y las librerias a utilizar.

10
11
  window=gtk_window_new (GTK_WINDOW_TOPLEVEL);
label=gtk_label_new("Hola Mundo");

La inicializacion de nuestra ventana, el párametro GTK_WINDOW_TOPLEVEL indica que queremos que la ventana pase por el administrador de ventanas para su decoración y emplazamiento, la incialización de la etiqueta simplemente le asigna el texto que desplegara.

13
 gtk_container_add(GTK_CONTAINER(window),label);

Colocamos nuestra etiqueta dentro de la ventana recien creada.

15
16
  gtk_widget_show (label);
  gtk_widget_show (window);

Estas lineas nos sirven para hacer visibles nuestros widgets y que sean manipulables por el usuario

18
  gtk_main();

Esta función será llamada en todos los programas en Gtk+ y sirve para poner en modo de espera a nuestro programa, y asi poder recibir y manejar cualquier evento ocurrido.

Por ultimo para compilar nuestro codigo nos dirigimos a la terminal y escribimos:

gcc holamundo.c -o holamundo `pkg-config --cflags --libs gtk+-2.0`

o

gcc holamundo.c -o holamundo $(pkg-config --cflags --libs gtk+-2.0)

Nótese que utilizamos pkg-config para la compilación de nuestro programa (facilmente instalado mediante un gestor de paquetes como el Synaptic), este programa funciona para localizar e incluir las librerías que necesitamos sin tener que escribir -I/isr/include/gtk-2.0, etc. Hay que advertir que el carácter utilizado es ” ` ” y no ” ‘ ” esto es de vital importancia si no desean frustrarse por que su codigo no compila a pesar de que ya checharon y rechecaron todas las malditas dependencias y… ejem. nuestro programa lucira asi si todo funciona correctamente.

holamundo

Para cerrar correctamente este programa debemos utilizar la combinación de teclas ctrl+c en la terminal, de lo contrario permanecerá ejecutandose aun si cerramos la ventana. Con esto, estamos listos para conocer señales, eventos y los dos widgets básicos en cualquier interfaz gráfica, botones y labels (etiquetas).

Tutorial Gtk+ 2: Instalacion de Gtk+ 2 en Linux

Gtk+ es, de manera parecida a Qt, un conjunto de herramientas usado para crear interfaz gráfica de usuario, escrito completamente en C, no se encuentra orientado a objetos, sin embargo “simula” estarlo,  al estar programado en C es bastante flexible con otros lenguajes y facilmente adaptable, la interfaz grafica de Gnome  (el entorno de escritorio de Ubuntu) esta creada con Gtk+.

Instalacion de Gtk con Gestor de paquetes.
Instalar Gtk con un gestor de paquetes como es el Synaptic de Ubuntu es bastante sencillo ya que solamente necesitamos localizar la libreria con el nombre de “libgtk2.0-dev” y nuestro magico gestor de paquetes resolvera las dependencias de librerias necesarias para que todo funcione correctamente.

Instalacion de Gtk+ con paquetes de distribución (O la ruta escénica)

El primer paso es conseguir el paquete de distribución de la página www.gtk.org de la sección de descargas de la misma, el segundo es extraerlo a la carpeta donde tendremos todos nuestros archivos de origen, esto lo hacemos con los comandos:

tar xvfz gtk+-2.0.0.tar.gz
tar xvfj gtk+-2.0.0.tar.bz2

Despues de hacer esto nos ubicamos en la carpeta donde se contienen todos los demas archivos y ejecutamos el script llamado configure el cual crea archivos makefile adecuados al sistema operativo, la manera mas comun de hacer esto es:

./configure --prefix=/opt/gtk

Despues de hacer esto simplemente hacemos uso de los archivos recien creados e instalamos con los siguientes comandos:

make
make install

Despues de esto puede que sea necesario hacerle saber al sistema operativo acerca de las nuevas librerias dinámicas esto lo hacemos ejecutando:

ldconfig

Una vez hecho esto al fin hemos conseguido instalar Gtk+ en uestra maquina con Linux, si ocurrel agun fallo a pesar de que ya se encuentra instalado Gtk+, lo mas probable es que se trate de alguna libreria de la cual depende gtk para compilar/ejecutar, la manera mas fácil de comprobar que nuestro Gtk+ fue instalado con exito es ejecutar en nuestra liena de comandos el demo que viene jutno con Gtk+:

gtk-demo

Con esto tenemos todo listo para crear nuestro “Hola Mundo” en Gtk+.