Interfacce grafiche per i nostri programmi in GTK+ – parte 2 –

Nella prima parte abbiamo creato la nostra prima finestra in Gtk+, adesso cercheremo di aggiungere alla nostra finestra tutti i controlli necessari per  interfacciarsi al meglio con l’utente finale.

Il widget button (e relativo segnale)

Per prima cosa aggiungiamo alla nostra finestra una bel tasto, che gestisce la chiusura della stessa, in poche parole un bottone che chiude la finestra come se cliccassimo la “X” in alto a destra (Figura 1).

#include <gtk/gtk.h>

static void destroy (GtkWidget*, gpointer);
static gboolean delete_event (GtkWidget*, GdkEvent*, gpointer);

int main (int argc, char *argv[])
{
//Aggiungiamo un nuovo widget e lo chiamiamo button.
GtkWidget *window, *button;
gtk_init (&argc, &argv);
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_title (GTK_WINDOW (window), “Hello World”);
gtk_window_set_gravity (GTK_WINDOW (window), GDK_GRAVITY_CENTER);
gtk_container_set_border_width (GTK_CONTAINER (window), 10);
gtk_widget_set_size_request (window, 200, 100);
g_signal_connect (G_OBJECT (window), “destroy”, G_CALLBACK (destroy), NULL);
g_signal_connect (G_OBJECT (window), “delete_event”, G_CALLBACK (delete_event), NULL);
//Creiamo il tasto con la label CHIUDI e con il mnemonico CTRL+C.
button = gtk_button_new_with_mnemonic (“_CHIUDI”);
//Gli diamo anche graficamente l’aspetto 3D.
gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NORMAL);
//Connettiamo il nostro bottone all’evento clicked e alla pressione del tasto richiamiamo la funzione destroy.
g_signal_connect_swapped (G_OBJECT (button), “clicked”, G_CALLBACK (destroy), NULL);
//Ultima cosa aggiungiamo il nostro bottone alla finestra che la consideriamo per questo esempio come un contenitore ddi oggetti widget.
gtk_container_add (GTK_CONTAINER (window), button);
gtk_widget_show_all (window);
gtk_main ();
return 0;
}

static void destroy (GtkWidget *window, gpointer data)
{
gtk_main_quit ();
}

static gboolean delete_event (GtkWidget *window, GdkEvent *event, gpointer data)
{
return FALSE;
}

Una prima premessa sui container

Un discorso a parte va fatto sui container; i container come descritto sul programma è un widget che può contenere altri widget, però nel caso appena descritto la nostra window potrà contenere sono un oggetto widget. Se volessimo più widget nel nostro contenitore, non dovremo utilizzare la nostra window ma dovremo utilizzare dei layout predefiniti in GTK+ (hbox, vbox, table…). A loro volta i layout possono essere usati come contenitori di widget.
I contenitori sono un po’ complicati da spiegare ma a sua volta molto semplici da usare una volta che si comincia ad avere un po’ più di confidenza con le GTK+, con calma si fa tutto.
I Signals e le Callback
Dopo aver fatto questa piccola premessa sui container ritorniamo al nostro bottone che permette la chiusura della nostra window, GTK+ permette inoltre di utilizzare la seguente riga di connessione al segnale di click:
g_signal_connect (G_OBJECT (button), “clicked”, G_CALLBACK (gtk_widget_destroy), (gpointer) window);
Praticamente al click del nostro bottone verrà richiamata la funzione gtk_widget_destroy alla quale verrà passata la nostra window per la definitiva chiusura. Quindi se al posto della nostra window come parametro passavamo il nostro button, dalla nostra window sparirà solamente il tasto che abbiamo creato.

In poche parole si può connettere ad un oggetto, o meglio, a qualsiasi oggetto widgets, un segnale, che può essere il semplice click, doppio click, etc… e appena questo segnale viene sollevato dall’oggetto widget a cui è connesso verrà eseguita la callback. Alla callback inoltre può essere passato un altro oggetto widget che subirà il segnale sollevato.

Il widget label

Adesso, al posto di un bottone mettiamo una label (etichetta) con la solita scritta “Ciao Mondo”, senza riscrivere tutto il codice andremo ad aggiungere un nuovo oggetto widget:

GtkWidget *window, *button, *label;

Andremo poi a commentare le righe:

button = gtk_button_new_with_mnemonic (“_CHIUDI”);
gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NORMAL);
g_signal_connect_swapped (G_OBJECT (button), “clicked”, G_CALLBACK (destroy), NULL);
gtk_container_add (GTK_CONTAINER (window), button);

Ed andremo a scrivere:

//Creiamo la nostra label.
label=gtk_label_new (“Ciao Mondo”);
//Facciamo in modo che non si possa selezionare il testo.
gtk_label_set_selectable (GTK_LABEL (label), FALSE);
//Aggiungiamo al nostro container (nel caso la nostra finestra) il tasto.
gtk_container_add (GTK_CONTAINER (window), label);
Ed ecco la nostra window con una bella label con la mitica frase “Ciao Mondo” (Figura 2):

Sicuramente a qualcuno vorrà provare a mettere sulla stessa window la label e il button utilizzando il comando gtk_container_add ma si accorgerà subito dalla compilazione che non potrà farlo!!! Il perchè? Perchè prima di aggiungere al container window i nostri widget (label e button) dovremo definire un layout sul quale inserirli. Quindi nella terza parte spiegheremo i principali layout messi a disposizione da GTK+!!! 😉