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 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<HTML>
<HEAD>
<META NAME="GENERATOR" CONTENT="SGML-Tools 1.0.9">
<TITLE>GTK Tutorial: Proseguiamo</TITLE>
<LINK HREF="gtk_tut_it-4.html" REL=next>
<LINK HREF="gtk_tut_it-2.html" REL=previous>
<LINK HREF="gtk_tut_it.html#toc3" REL=contents>
</HEAD>
<BODY BGCOLOR="#FFFFFF">
<A HREF="gtk_tut_it-4.html">Avanti</A>
<A HREF="gtk_tut_it-2.html">Indietro</A>
<A HREF="gtk_tut_it.html#toc3">Indice</A>
<HR NOSHADE>
<H2><A NAME="s3">3. Proseguiamo</A></H2>
<P>
<P>
<H2><A NAME="ss3.1">3.1 Tipi di Dato</A>
</H2>
<P>Ci sono alcune cose che avrete probabilmente notato nei precedenti esempi che
hanno bisogno di una spiegazione. I gint, gchar ecc. che vedete sono tipi di dato
(typedef) riferiti rispettivamente a int e char. Questo viene fatto per rimediare
alle scomode dipendenze dalle dimensioni di semplici tipi di dato quando si fanno
dei calcoli. Un buon esempio è ``gint32'' il quale sarà un tipo di
dato riferito ad un intero a 32 bit per tutte le piattaforme, sia per gli x86 che
per gli per gli alpha a 64 bit.
I tipi di dato sono ben spiegati più avanti e molto intuitivi. Sono definiti
in glib/glib.h (il quale viene incluso da gtk.h).
<P>Noterete anche la possibilità di utilizzare un GtkWidget quando la funzione
richiede un GtkObject. GTK è una libreria orienta agli oggetti ed un widget
è un oggetto.
<P>
<H2><A NAME="ss3.2">3.2 Altri Dettagli sui Segnali</A>
</H2>
<P>Diamo un'altra occhiata alla dichiarazione della funzione gtk_signal_connect.
<P>
<BLOCKQUOTE><CODE>
<PRE>
gint gtk_signal_connect (GtkObject *object, gchar *name,
GtkSignalFunc func, gpointer func_data);
</PRE>
</CODE></BLOCKQUOTE>
Notate il valore di ritorno definito come gint? Questo è un identificatore
per la vostra funzione di callback. Come detto sopra, si possono avere più
funzioni di ritorno per ogni segnale e per ogni ogetto a seconda delle
necessità, ed ognuna sarà eseguita in sequenza, nell'ordine in cui
è stata collegata.
<P>Questo identificatore vi permette di rimuovere una funzione dalla lista delle
funzioni di ritorno tramite la seguente chiamata
<P>
<BLOCKQUOTE><CODE>
<PRE>
void gtk_signal_disconnect (GtkObject *object,
gint id);
</PRE>
</CODE></BLOCKQUOTE>
Così, passando il widget da cui si vuole rimuovere il gestore di segnale e
l'identificativo restituito da una delle funzioni signal_connect, si può
rimuovere il gestore di segnale che si desidera dal widget.
<P>Un'altra funzione, usata per rimuovere tutti i segnali di un widget in una volta
sola è:
<P>
<BLOCKQUOTE><CODE>
<PRE>
gtk_signal_handlers_destroy (GtkObject *object);
</PRE>
</CODE></BLOCKQUOTE>
<P>Questa chiamata è abbastanza auto esplicativa. Semplicemente rimuove tutti
i segnali collegati al widget che si passa alla funzione come argomento.
<P>
<H2><A NAME="ss3.3">3.3 Miglioriamo Hello World</A>
</H2>
<P>Diamo un'occhiata ad una versione migliorata di Hello World con altri esempi
sulle callback. Questo ci introdurrà anche al nostro prossimo argomento,
l'impacchettamento dei widget.
<P>
<BLOCKQUOTE><CODE>
<PRE>
/* helloworld2.c */
#include <gtk/gtk.h>
/* La nostra funzione di callback migliorata. I dati passati a questa
* vengono stampati su stdout. */
void callback (GtkWidget *widget, gpointer data)
{
g_print ("Hello again - %s was pressed\n", (char *) data);
}
/* Un'altra callback */
void delete_event (GtkWidget *widget, gpointer data)
{
gtk_main_quit ();
}
int main (int argc, char *argv[])
{
/* GtkWidget e' il tipo di dato per i widget */
GtkWidget *window;
GtkWidget *button;
GtkWidget *box1;
/* Questa funzione e' invocata in tutte le applicazioni GTK, gli
argomenti sono analizzati e restituiti all'applicazione. */
gtk_init (&argc, &argv);
/* Crea una nuova finestra */
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
/* Questa e' una nuova chiamata. Assegna "Hello Buttons" come titolo
della nostra finestra */
gtk_window_set_title (GTK_WINDOW (window), "Hello Buttons!");
/* Qui settiamo il gestore per il segnale "delete_event" che
immediatamente esce dalla applicazione.
gtk_signal_connect (GTK_OBJECT (window), "delete_event",
GTK_SIGNAL_FUNC (delete_event), NULL);
/* predispone il bordo della finestra */
gtk_container_border_width (GTK_CONTAINER (window), 10);
/* creiamo una scatola dove mettere tutti i widget. Questa è descritta
dettagliatamente nella sezione "packing". La scatola non è realmente
visibile, è solamente usata per sistemare i widget. */
box1 = gtk_hbox_new(FALSE, 0);
/* Inseriamo la scatola nella finestra */
gtk_container_add (GTK_CONTAINER (window), box1);
/* Creiamo un nuovo bottone con etichetta "Button 1" */
button = gtk_button_new_with_label ("Button 1");
/* Quando il bottone e' premuto, noi invocheremo la funzione di callback,
con un puntatore alla stringa "button 1" come proprio argomento) */
gtk_signal_connect (GTK_OBJECT (button), "clicked",
GTK_SIGNAL_FUNC (callback), (gpointer) "button 1");
/* invece di aggiungerlo alla finestra, lo inseriamo nella scatola invisibile,
la quale e' stata inserita nella finstra. */
gtk_box_pack_start(GTK_BOX(box1), button, TRUE, TRUE, 0);
/* Ricordati sempre questo passo. Dice a GTK che la preparazione di questo
bottone e' finita e che quindi puo' essere mostrato. */
gtk_widget_show(button);
/* Facciamo la stessa cosa per il secondo bottone. */
button = gtk_button_new_with_label ("Button 2");
/* Chiamiamo la stessa funzione ma passandogli un argomento differente,
gli passiamo un puntatore alla stringa "button 2" */
gtk_signal_connect (GTK_OBJECT (button), "clicked",
GTK_SIGNAL_FUNC (callback), (gpointer) "button 2");
gtk_box_pack_start(GTK_BOX(box1), button, TRUE, TRUE, 0);
/* L'ordine nel quale i bottoni sono visualizzati non e' realmente importante,
ma io ti raccomando di mostrare per ultima la finestra cosi' che tutto
sia visualizzato in una volta sola */
gtk_widget_show(button);
gtk_widget_show(box1);
gtk_widget_show (window);
/* e ora ci mettiamo in gtk_main e aspettiamo che il diverimento inizi.
gtk_main ();
return 0;
}
</PRE>
</CODE></BLOCKQUOTE>
<P>Compilate questo programma usando gli stessi argomenti di link del nostro primo
esempio. Noterete che questa volta non c'è un modo semplice per uscire
dal programma, si deve usare il nostro window manager o la linea di comando per
uccidere l'applicazione.
Un buon esercizio per il lettore è quello di inserire un tezo bottone
``quit'' che faccia uscire dal programma. Potete anche divertirvi con le opzioni
di gtk_box_pack_start() mentre leggete il prossimo capitolo. Provate a
ridimensionare la finestra ed a osservare cosa succede.
<P>Solo una piccola nota: c'è un'altra definizione di gtk_window_new() -
GTK_WINDOW_DIALOG. Questa interagisce con il window manager in un modo un po'
diverso, e dovrebbe essere usata per finestre temporanee.
<P>
<HR NOSHADE>
<A HREF="gtk_tut_it-4.html">Avanti</A>
<A HREF="gtk_tut_it-2.html">Indietro</A>
<A HREF="gtk_tut_it.html#toc3">Indice</A>
</BODY>
</HTML>
|