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 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<HTML>
<HEAD>
<META NAME="GENERATOR" CONTENT="SGML-Tools 1.0.9">
<TITLE>GTK Tutorial: Il Widget Bottone (Button)</TITLE>
<LINK HREF="gtk_tut_it-7.html" REL=next>
<LINK HREF="gtk_tut_it-5.html" REL=previous>
<LINK HREF="gtk_tut_it.html#toc6" REL=contents>
</HEAD>
<BODY BGCOLOR="#FFFFFF">
<A HREF="gtk_tut_it-7.html">Avanti</A>
<A HREF="gtk_tut_it-5.html">Indietro</A>
<A HREF="gtk_tut_it.html#toc6">Indice</A>
<HR NOSHADE>
<H2><A NAME="s6">6. Il Widget Bottone (Button)</A></H2>
<H2><A NAME="ss6.1">6.1 Bottoni Normali</A>
</H2>
<P>Ormai abbiamo visto tutto quello che c'è da vedere riguardo all'oggetto
``bottone''. E' piuttosto semplice, ma ci sono due modi per crare un bottone.
Potete usare gtk_button_new_with_label() per creare un bottone con una
etichetta, o usare gtk_button_new() per creare un bottone vuoto. In tal caso è poi
vostro compito impacchettare un'etichetta o una pixmap sul bottone creato.
Per fare ciò, create una nuova scatola, e poi impacchettateci i vostri
oggetti usando la solita gtk_box_pack_start, e infine usate la funzione
gtk_container_add per impacchettare la scatola nel bottone.
<P>Ecco un esempio di utilizzo di gtk_button_new per creare un bottone con
un'immagine ed un'etichetta su di sè. Ho separato il codice usato per
creare la scatola in modo che lo possiate usare nei vostri programmi.
<P>
<BLOCKQUOTE><CODE>
<PRE>
/* buttons.c */
#include <gtk/gtk.h>
/* crea una nuova hbox contenente un'immagine ed un'etichetta
* e ritorna la scatola creata. */
GtkWidget *xpm_label_box (GtkWidget *parent, gchar *xpm_filename, gchar *label_text)
{
GtkWidget *box1;
GtkWidget *label;
GtkWidget *pixmapwid;
GdkPixmap *pixmap;
GdkBitmap *mask;
GtkStyle *style;
/* creare una scatola per una xpm ed una etichetta */
box1 = gtk_hbox_new (FALSE, 0);
gtk_container_border_width (GTK_CONTAINER (box1), 2);
/* ottengo lo stile del bottone. Penso che sia per avere il colore
* dello sfondo. Se qualcuno sa il vero motivo, è pregato di dirmelo. */
style = gtk_widget_get_style(parent);
/* e ora via con le faccende dell'xpm stuff. Carichiamo l'xpm*/
pixmap = gdk_pixmap_create_from_xpm (parent->window, &mask,
&style->bg[GTK_STATE_NORMAL],
xpm_filename);
pixmapwid = gtk_pixmap_new (pixmap, mask);
/* creiamo l'etichetta per il bottone */
label = gtk_label_new (label_text);
/* impacchettiamo la pixmap e l'etichetta nella scatola */
gtk_box_pack_start (GTK_BOX (box1),
pixmapwid, FALSE, FALSE, 3);
gtk_box_pack_start (GTK_BOX (box1), label, FALSE, FALSE, 3);
gtk_widget_show(pixmapwid);
gtk_widget_show(label);
return (box1);
}
/* la nostra solita funzione di callback */
void callback (GtkWidget *widget, gpointer data)
{
g_print ("Hello again - %s was pressed\n", (char *) data);
}
int main (int argc, char *argv[])
{
/* GtkWidget è il tipo per contenere gli oggetti */
GtkWidget *window;
GtkWidget *button;
GtkWidget *box1;
gtk_init (&argc, &argv);
/* creiamo una nuova finestra */
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_title (GTK_WINDOW (window), "Pixmap'd Buttons!");
/* E' una buona idea fare questo per tutte le finestre. */
gtk_signal_connect (GTK_OBJECT (window), "destroy",
GTK_SIGNAL_FUNC (gtk_exit), NULL);
gtk_signal_connect (GTK_OBJECT (window), "delete_event",
GTK_SIGNAL_FUNC (gtk_exit), NULL);
/* assegnamo lo spessore del bordo della finestra */
gtk_container_border_width (GTK_CONTAINER (window), 10);
gtk_widget_realize(window);
/* creiamo un nuovo bottone */
button = gtk_button_new ();
/* Ormai dovreste esservi abituati a vedere la maggior parte di
* queste funzioni */
gtk_signal_connect (GTK_OBJECT (button), "clicked",
GTK_SIGNAL_FUNC (callback), (gpointer) "cool button");
/* questa chiama la nostra funzione di creazione di scatole */
box1 = xpm_label_box(window, "info.xpm", "cool button");
/* impacchetta e mostra tutti i nostri oggetti */
gtk_widget_show(box1);
gtk_container_add (GTK_CONTAINER (button), box1);
gtk_widget_show(button);
gtk_container_add (GTK_CONTAINER (window), button);
gtk_widget_show (window);
/* mettiti in gtk_main e aspetta che cominci il divertimento! */
gtk_main ();
return 0;
}
</PRE>
</CODE></BLOCKQUOTE>
La funzione xpm_label_box può essere usata per impacchettare delle xpm
e delle etichette su qualsiasi oggetto che può essere un contenitore.
<P>
<H2><A NAME="ss6.2">6.2 Bottoni a Commutazione (Toggle Buttons)</A>
</H2>
<P>I bottoni a commutazione sono molto simili ai bottoni normali, tranne che per il
fatto che essi si trovano sempre in uno di due stati, che si alternano ad ogni
click. Possono trovarsi nello stato ``premuto'', e quando li si ripreme, tornano
ad essere sollevati. Ri-clickandoli, torneranno giù.
<P>I bottoni a commutazione sono la base per i bottoni di controllo (check button) e
per i radio-bottoni, e quindi molte delle chiamate disponibili per i bottoni
a commutazione vengono ereditati dai radio-bottoni e dai bottoni di controllo.
Ma vedremo questi aspetti nel momento in cui li incontreremo.
<P>Creare un nuovo bottone a commutazione:
<P>
<BLOCKQUOTE><CODE>
<PRE>
GtkWidget* gtk_toggle_button_new (void);
GtkWidget* gtk_toggle_button_new_with_label (gchar *label);
</PRE>
</CODE></BLOCKQUOTE>
<P>Come potete immaginare, queste funzioni lavorano in modo identico che per
i bottoni normali. La prima crea un bottone a commutazione vuoto e la seconda un
bottone con un'etichetta.
<P>Per ottenere lo stato dei widget a commutazione, compresi i radio-bottoni e i
bottoni di controllo, si può usare una macro come mostrato nell'esempio
più sotto. In questo modo lo stato dell'oggetto commutabile viene valutato in
una funzione di ritorno. Il segnale emesso dai bottoni a commutazione
(toggle button, il radio button o il check button) che ci interessa è il segnale
``toggled''. Per controllare lo stato di questi bottoni, create un gestore di
segnali che catturi il ``toggled'', e usate la macro per determinare
il suo stato. La funzione di callback avrà un aspetto più o meno così:
<P>
<BLOCKQUOTE><CODE>
<PRE>
void toggle_button_callback (GtkWidget *widget, gpointer data)
{
if (GTK_TOGGLE_BUTTON (widget)->active)
{
/* Se il programma si è arrivato a questo punto, il bottone
* a commutazione è premuto */
} else {
/* il bottone è sollevato */
}
}
</PRE>
</CODE></BLOCKQUOTE>
<P>
<P>
<BLOCKQUOTE><CODE>
<PRE>
void gtk_toggle_button_set_state (GtkToggleButton *toggle_button,
gint state);
</PRE>
</CODE></BLOCKQUOTE>
<P>La chiamata qui sopra può essere usata per fare l'assegnazione dello stato
del bottone a commutazione e dei suoi figli, il radio-bottone e il bottone di
controllo. Passando come primo argomento a questa funzione il vostro bottone e
come secondo argomento il valore TRUE o FALSE, si può specificare se il
bottone deve essere sollevato (rilasciato) o abbassato (premuto). Il valore
di difetto è sollevato, cioè FALSE.
<P>Notate che quando usate la funzione gtk_toggle_button_set_state(), e lo
stato viene cambiato, si ha il risultato che il bottone emette il segnale
``clicked''.
<P>
<BLOCKQUOTE><CODE>
<PRE>
void gtk_toggle_button_toggled (GtkToggleButton *toggle_button);
</PRE>
</CODE></BLOCKQUOTE>
<P>Questa funzione semplicemente commuta il bottone, ed emette il segnale ``toggled''.
<P>
<H2><A NAME="ss6.3">6.3 Bottoni di Controllo (Check Buttons)</A>
</H2>
<P>I bottoni di controllo ereditano molte proprietà e funzioni dal bottone a commutazione,
ma hanno un aspetto un po' diverso. Invece di essere bottoni contenenti del testo,
si tratta di quadratini con del testo alla propria destra. Questi bottoni sono
spesso usati nelle applicazioni per commutare fra lo stato attivato e disattivato delle
opzioni.
<P>Le due funzioni di creazione sono analoghe a quelle del bottone normale..
<P>
<BLOCKQUOTE><CODE>
<PRE>
GtkWidget* gtk_check_button_new (void);
GtkWidget* gtk_check_button_new_with_label (gchar *label);
</PRE>
</CODE></BLOCKQUOTE>
<P>La funzione new_with_label crea un bottone di controllo con una etichetta
a fianco di esso.
<P>Per controllare lo stato del check button si opera in modo identico al bottone
a commutazione.
<P>
<H2><A NAME="ss6.4">6.4 Radio-Bottoni (Radio Buttons)</A>
</H2>
<P>I radio-bottoni sono simili ai bottoni di controllo, tranne che per il
fatto che sono sempre raggruppati in modo che solo uno alla volta di essi
può essere selezionato (premuto). Tornano utili quando nella propria applicazione
si ha bisogno di selezionare una opzione da una breve lista.
<P>La creazione di un nuovo radio-bottone si fa con una di queste chiamate:
<P>
<BLOCKQUOTE><CODE>
<PRE>
GtkWidget* gtk_radio_button_new (GSList *group);
GtkWidget* gtk_radio_button_new_with_label (GSList *group,
gchar *label);
</PRE>
</CODE></BLOCKQUOTE>
<P>Avrete notato l'argomento in più che c'è in queste chiamate. Queste hanno
infatti bisogno dela specificazione di un ``gruppo'' per svolgere il loro compito.
Per il primo bottone di un gruppo si deve passare come primo argomento il valore
NULL. Dopodiché potete creare un gruppo usando la funzione:
<P>
<BLOCKQUOTE><CODE>
<PRE>
GSList* gtk_radio_button_group (GtkRadioButton *radio_button);
</PRE>
</CODE></BLOCKQUOTE>
<P>
<P>La cosa importante da ricordare è che gtk_radio_button_group va chiamata ogni volta che si aggiunge un nuovo bottone al gruppo, con il preceente bottone passato come argomento. Il risultato viene poi passato nella chiamata a gtk_radio_button_new o a gtk_radio_button_new_with_label. Ciò permette di creare una catena di bottoni. L'esempio più sotto dovrebbe chiarire questo punto.
<P>E' poi una buona idea stabiire quale dev'essere il bottone premuto per difetto, usando:
<P>
<BLOCKQUOTE><CODE>
<PRE>
void gtk_toggle_button_set_state (GtkToggleButton *toggle_button,
gint state);
</PRE>
</CODE></BLOCKQUOTE>
<P>Questa funzione è descritta nella sezione sui bottoni a commutazione, e funziona
nello stesso identico modo.
<P>
<P>Nel seguente esempio creiamo un gruppo di tre radio-bottoni.
<P>
<BLOCKQUOTE><CODE>
<PRE>
/* radiobuttons.c */
#include <gtk/gtk.h>
#include <glib.h>
void close_application( GtkWidget *widget, gpointer data ) {
gtk_main_quit();
}
main(int argc,char *argv[])
{
static GtkWidget *window = NULL;
GtkWidget *box1;
GtkWidget *box2;
GtkWidget *button;
GtkWidget *separator;
GSList *group;
gtk_init(&argc,&argv);
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_signal_connect (GTK_OBJECT (window), "delete_event",
GTK_SIGNAL_FUNC(close_application),
NULL);
gtk_window_set_title (GTK_WINDOW (window), "radio buttons");
gtk_container_border_width (GTK_CONTAINER (window), 0);
box1 = gtk_vbox_new (FALSE, 0);
gtk_container_add (GTK_CONTAINER (window), box1);
gtk_widget_show (box1);
box2 = gtk_vbox_new (FALSE, 10);
gtk_container_border_width (GTK_CONTAINER (box2), 10);
gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
gtk_widget_show (box2);
button = gtk_radio_button_new_with_label (NULL, "button1");
gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
gtk_widget_show (button);
group = gtk_radio_button_group (GTK_RADIO_BUTTON (button));
button = gtk_radio_button_new_with_label(group, "button2");
gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (button), TRUE);
gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
gtk_widget_show (button);
group = gtk_radio_button_group (GTK_RADIO_BUTTON (button));
button = gtk_radio_button_new_with_label(group, "button3");
gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
gtk_widget_show (button);
separator = gtk_hseparator_new ();
gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
gtk_widget_show (separator);
box2 = gtk_vbox_new (FALSE, 10);
gtk_container_border_width (GTK_CONTAINER (box2), 10);
gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
gtk_widget_show (box2);
button = gtk_button_new_with_label ("close");
gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
GTK_SIGNAL_FUNC(close_application),
GTK_OBJECT (window));
gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
gtk_widget_grab_default (button);
gtk_widget_show (button);
gtk_widget_show (window);
gtk_main();
return(0);
}
</PRE>
</CODE></BLOCKQUOTE>
<P>La cosa può essere accorciata un po' usando la seguente sintassi,
che elimina la necessità di una variabile per contenere la lista di bottoni:
<P>
<BLOCKQUOTE><CODE>
<PRE>
button2 = gtk_radio_button_new_with_label(
gtk_radio_button_group (GTK_RADIO_BUTTON (button1)),
"button2");
</PRE>
</CODE></BLOCKQUOTE>
<P>
<P>
<HR NOSHADE>
<A HREF="gtk_tut_it-7.html">Avanti</A>
<A HREF="gtk_tut_it-5.html">Indietro</A>
<A HREF="gtk_tut_it.html#toc6">Indice</A>
</BODY>
</HTML>
|