Aprendiendo GTK+: Primeros pasos

Publicado en C/C++, GTK el 14 de January, 2008 por Fran.

Iniciando GTK+

Antes de empezar con otra cosa, voy a explicar como iniciar GTK+ en nuestra aplicación. Los pasos más importantes son los siguientes:

  1. Hay que inicializar el toolkit, para ello se llama a la siguiente función:
    gtk_init (int *argc, char **argv[]);

    Esta función se usa para iniciar el toolkit y parsear los parámetros relativos a GTK+ que reciba nuestra aplicación, de modo que GTK+ los use y no nos tengamos de preocupar de parsearlos nosotros, dichos parámetros son eliminados de la lista.

  2. Ejecutar el main loop (o bucle principal), éste se encarga de dejar a la aplicación en un bucle, hasta que llamemos a la función de salida de dicho bucle, en el cual se tratan las diferentes señales que se produzcan en nuestra aplicación. Para ello se llama a la siguiente función:
    gtk_main ();

    Para salir del bucle se llama a la siguiente función:

    gtk_main_quit ();
  3. Obviamente, antes de ejecutar el main loop se deberán tener los manejadores de las señales asignados y todas las variables inicializadas, ya que una vez se ejecuta no tendremos control sobre nada de la aplicación.

Señales

Una vez explicado como se inicia y ejecuta GTK+, hay que conocer como se manejan las diferentes señales de los widgets de GTK+. Para ello, se deben conocer las diferentes señales que lanza cada widget y los prototipos de funciones asociadas a cada señal, normalmente todas usan el mismo prototipo pero algunas tienen un prototipo asociado que es diferente a los demás. De todos modos, se usan las mismas funciones para conectar las señales a su manejador.

Las funciones para conectar las señales a un manejador son:

gulong g_signal_connect (gpointer *object, const gchar *name,
          GCallback func, gpointer func_data);

Donde los parámetros son:

  • object: El widget que lanza la señal. Aunque se debe pasar como un objeto de GObject, esto no es importante ya que realmente es un mero casting y no hay que saber como funciona GObject.
  • name: El nombre de la señal del widget a la que queremos conectar un manejador.
  • func: El nombre de la función del manejador.
  • func_data: El parámetro de la función del manejador.

Las funciones del manejador de cada señal deben tener un prototipo definido en la documentación de la API de GTK+, aunque normalmente suelen ser uno de estos dos:

void func (GtkWidget *widget, gpointer data);
gboolean func (GtkWidget *widget, GdkEvent *event, gpointer data);

El primer prototipo es el más usado (por lo menos en lo que yo he visto), el segundo se suele usar en algunas señales específicas que cuando se lanzan puede que una vez tratadas lancen otra a continuación o no (de ahí el valor de retorno de tipo gboolean).

Lo importante es saber como se conectan las señales a su manejador, los prototipos siempre es mejor consultarlos en la API de GTK+ para la señal que queremos tratar, por si las moscas.

Hola mundo

#include <gtk/gtk.h>

/* delete_event: Decide si destruir la ventana GTK+ o no */
static gboolean delete_event (GtkWidget *widget,
					GdkEvent *event, gpointer data) {

	/* Si se devuelve TRUE no se lanza la señal "destroy" */
	//g_print ("delete_event: No se destruye la ventana.\n");
	//return TRUE;

	/* Si se devuelve FALSE se lanza la señal "destroy" */
	g_print ("delete_event: Se destruye la ventana.\n");
	return FALSE;
}

/* destroy: Termina la ejecución de la aplicación GTK+ */
static void destroy (GtkWidget *widget, gpointer data) {

	/* Fin de la ejecución de GTK+ */
	gtk_main_quit ();
}

static void hola_mundo (GtkWidget *widget, gpointer data) {

	g_print ("hola mundo\n");
}

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

	GtkWidget *window;
	GtkWidget *button;

	gtk_init (&argc, &argv);

	window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
	g_signal_connect (G_OBJECT (window), "delete_event",
				G_CALLBACK (delete_event), NULL);
	g_signal_connect (G_OBJECT (window), "destroy",
				G_CALLBACK (destroy), NULL);

	button = gtk_button_new_with_label ("Hola");
	g_signal_connect (G_OBJECT (button), "clicked",
				G_CALLBACK (hola_mundo), NULL);

	gtk_container_add (GTK_CONTAINER (window), button);
	gtk_widget_show_all (window);

	gtk_main ();

	return 0;
}

En principio, no hace falta que entendáis todo, ya que hay creación de widgets y cosas que todavía no he explicado, pero más o menos podéis ver la idea que hay detrás de usar GTK+.

Para compilarlo, se debe ejecutar lo siguiente (usando gcc como compilador):

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

Sin comentarios

Escribe un comentario