{"id":452,"date":"2019-11-03T23:12:06","date_gmt":"2019-11-03T22:12:06","guid":{"rendered":"http:\/\/www.forlex.it\/?p=452"},"modified":"2021-11-17T09:18:41","modified_gmt":"2021-11-17T08:18:41","slug":"interfacce-grafiche-per-i-nostri-programmi-in-gtk-parte-4","status":"publish","type":"post","link":"http:\/\/www.forlex.it\/index.php\/2019\/11\/03\/interfacce-grafiche-per-i-nostri-programmi-in-gtk-parte-4\/","title":{"rendered":"Interfacce grafiche per i nostri programmi in GTK+ &#8211; parte 4 &#8211;"},"content":{"rendered":"\n<p>Adesso andremo a parlare di quegli oggetti base GTK+ utili all&#8217;utente per interagire con la nostra finestra o interfaccia GTK+.<br><br>Usare gli STOCK ITEM<br><br>Iniziamo con il parlare dei tasti gi\u00e0 predefiniti ovvero quei tasti che hanno gi\u00e0 di base un&#8217;icona al proprio interno ed hanno gi\u00e0 definita l&#8217;operazione che deve essere compiuta in caso di pressione del tasto. Anche se a dire il vero la callback da eseguire alla pressione del tasto pu\u00f2 essere anche cambiata, vediamo subito un esempio:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote\"><p>#include &lt;gtk\/gtk.h&gt;<\/p><p>static void destroy (GtkWidget*, gpointer);<br>static gboolean delete_event (GtkWidget*, GdkEvent*, gpointer);<\/p><p>int main (int argc, char *argv[])<br>{<br>\/* Inizializzo i miei oggetti. *\/<br>GtkWidget *window, *button;<br>gtk_init (&amp;argc, &amp;argv);<br>window = gtk_window_new (GTK_WINDOW_TOPLEVEL);<br>gtk_window_set_title (GTK_WINDOW (window), &#8220;STOCK&#8221;);<br>gtk_container_set_border_width (GTK_CONTAINER (window), 10);<br>gtk_widget_set_size_request (window, 200, 100);<br>\/\/ Creiamo il tasto utilizzando la configurazione base per un tasto di chiusura della nostra finestra.<br>button = gtk_button_new_from_stock (GTK_STOCK_CLOSE);<br>\/\/ Connettiamo al segnale di clicked del tasto la chiamata alla funzione di distruzione della widget e gli passiamo come parametro la nostra finestra.<br>g_signal_connect_swapped (G_OBJECT (button), &#8220;clicked&#8221;, G_CALLBACK (gtk_widget_destroy), (gpointer) window);<br>gtk_container_add (GTK_CONTAINER (window), button);<br>g_signal_connect (G_OBJECT (window), &#8220;destroy&#8221;, G_CALLBACK (destroy), NULL);<br>g_signal_connect (G_OBJECT (window), &#8220;delete_event&#8221;, G_CALLBACK (delete_event), NULL);<br>gtk_widget_show_all (window);<br>gtk_main ();<br>return 0;<br>}<\/p><p>static void destroy (GtkWidget *window, gpointer data)<br>{<br>gtk_main_quit ();<br>}<\/p><p>static gboolean delete_event (GtkWidget *window, GdkEvent *event, gpointer data)<br>{<br>return FALSE;<br>}<\/p><\/blockquote>\n\n\n\n<p><br>Il tutto dovrebbe risultare coma la Figura 1 qui sotto inserita:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" width=\"204\" height=\"125\" src=\"http:\/\/www.forlex.it\/wp-content\/uploads\/2019\/11\/gtk\/GTK-part4-win-1.png\" alt=\"\" class=\"wp-image-298\" srcset=\"http:\/\/www.forlex.it\/wp-content\/uploads\/2019\/11\/gtk\/GTK-part4-win-1.png 204w, http:\/\/www.forlex.it\/wp-content\/uploads\/2019\/11\/gtk\/GTK-part4-win-1-100x61.png 100w, http:\/\/www.forlex.it\/wp-content\/uploads\/2019\/11\/gtk\/GTK-part4-win-1-150x92.png 150w, http:\/\/www.forlex.it\/wp-content\/uploads\/2019\/11\/gtk\/GTK-part4-win-1-200x123.png 200w\" sizes=\"(max-width: 204px) 100vw, 204px\" \/><\/figure>\n\n\n\n<p>Come si \u00e8 gi\u00e0 accennato in precedenza gli stock button non sono proprio legati alla callback che rappresentano dato che pu\u00f2 essere cambiata in qualsiasi momento, ma ci saranno utili per avere gi\u00e0 dei tasti pronti all&#8217;uso.<br><br><strong>I Toggle Buttons<\/strong><br><br>I toggle buttons sono degli oggetti widget che alla loro pressione cambiano lo stato da attivo in disattivo! In poche parole la pressione di un tasto implica lo stato attivo o non di un altro tasto e viceversa.<br>Proviamo il seguente programmino:<br><br><\/p>\n\n\n\n<blockquote class=\"wp-block-quote\"><p>#include &lt;gtk\/gtk.h&gt;<\/p><p>static void destroy (GtkWidget*, gpointer);<br>static gboolean delete_event (GtkWidget*, GdkEvent*, gpointer);<br>\/\/ Funzione che gestir\u00e0 lo stato attivo o disattivo del tasto a seconda del tasto premuto.<br>static void button_toggled (GtkToggleButton*, GtkWidget*);<\/p><p>int main (int argc, char *argv[])<br>{<br>\/* Inizializzo i miei oggetti. *\/<br>GtkWidget *window, *vbox, *toggle1, *toggle2;<br>gtk_init (&amp;argc, &amp;argv);<br>window = gtk_window_new (GTK_WINDOW_TOPLEVEL);<br>gtk_window_set_title (GTK_WINDOW (window), &#8220;TOGGLE&#8221;);<br>gtk_container_set_border_width (GTK_CONTAINER (window), 10);<br>gtk_widget_set_size_request (window, 200, 100);<br>\/\/ Definiamo un vertical box come container per i nostri oggetti.<br>vbox = gtk_vbox_new (TRUE, 5);<br>\/\/ Creiamo i noostri toggle button con un tasto mnemoonico.<br>toggle1 = gtk_toggle_button_new_with_mnemonic (&#8220;_Attiva il tasto&#8221;);<br>toggle2 = gtk_toggle_button_new_with_mnemonic (&#8220;_Disattiva il tasto&#8221;);<br>\/\/ Aggiungiamo i nostri bottoni al nostro vertical box.<br>gtk_box_pack_start_defaults (GTK_BOX (vbox), toggle1);<br>gtk_box_pack_start_defaults (GTK_BOX (vbox), toggle2);<br>gtk_container_add (GTK_CONTAINER (window), vbox);<br>\/\/ Connettiamo i bottoni da noi creati alla nostra funzione di callback di toggled passandogli come parametro l&#8217;altro bottone.<br>g_signal_connect (G_OBJECT (toggle1), &#8220;toggled&#8221;, G_CALLBACK (button_toggled), (gpointer) toggle2);<br>g_signal_connect (G_OBJECT (toggle2), &#8220;toggled&#8221;, G_CALLBACK (button_toggled), (gpointer) toggle1);<br>g_signal_connect (G_OBJECT (window), &#8220;destroy&#8221;, G_CALLBACK (destroy), NULL);<br>g_signal_connect (G_OBJECT (window), &#8220;delete_event&#8221;, G_CALLBACK (delete_event), NULL);<br>gtk_widget_show_all (window);<br>gtk_main ();<br>return 0;<br>}<\/p><p>static void destroy (GtkWidget *window, gpointer data)<br>{<br>gtk_main_quit ();<br>}<\/p><p>static gboolean delete_event (GtkWidget *window, GdkEvent *event, gpointer data)<br>{<br>return FALSE;<br>}<\/p><p>static void button_toggled (GtkToggleButton *toggle, GtkWidget *other_toggle)<br>{<br>\/\/ Se il tasto premuto e attivo cio\u00e8 premuto.<br>if (gtk_toggle_button_get_active (toggle))<br>{<br> \/\/ Disattivo l&#8217;altro tasto, la sensibilit\u00e0.<br> gtk_widget_set_sensitive (other_toggle, FALSE);<br>}else{<br> \/\/ Attivo il tasto, lo rendo sensibile alla pressione.<br> gtk_widget_set_sensitive (other_toggle, TRUE);<br>}<br>}<\/p><\/blockquote>\n\n\n\n<p><br>Il tutto dovrebbe risultare come in Figura 2:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" width=\"204\" height=\"125\" src=\"http:\/\/www.forlex.it\/wp-content\/uploads\/2019\/11\/gtk\/GTK-part4-win-2.png\" alt=\"\" class=\"wp-image-299\" srcset=\"http:\/\/www.forlex.it\/wp-content\/uploads\/2019\/11\/gtk\/GTK-part4-win-2.png 204w, http:\/\/www.forlex.it\/wp-content\/uploads\/2019\/11\/gtk\/GTK-part4-win-2-100x61.png 100w, http:\/\/www.forlex.it\/wp-content\/uploads\/2019\/11\/gtk\/GTK-part4-win-2-150x92.png 150w, http:\/\/www.forlex.it\/wp-content\/uploads\/2019\/11\/gtk\/GTK-part4-win-2-200x123.png 200w\" sizes=\"(max-width: 204px) 100vw, 204px\" \/><\/figure>\n\n\n\n<p>\nSi possono impostare diversi flag nell&#8217;esempio si \u00e8 usato quello sulla sensibilit\u00e0 di un tasto. Per gli altri flag si rimanda ad internet oppure a manuali specifici.<\/p>\n\n\n\n<p><strong>Check Buttons<\/strong><\/p>\n\n\n\n<p>In alternativa ai toggle buttons visti in precedenza, che a volte possono essere ingombranti \u00e8 preferibile usare i check buttons, molto meno ingrombranti dei tasti, vediamo e commentiamo il seguente esempio.<br>Il tutto e&nbsp; l&#8217;inizializzazione dei check buttons sono del tutto simili ai toggle buttons visti in precedenza:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote\"><p>#include &lt;gtk\/gtk.h&gt;<\/p><p>static void destroy (GtkWidget*, gpointer);<br>static gboolean delete_event (GtkWidget*, GdkEvent*, gpointer);<br>static void check_toggled (GtkToggleButton*, GtkWidget*);<\/p><p>int main (int argc, char *argv[])<br>{<br>\/\/ Definiamo il container window, un container vertical box tre tasti check buttons ed un tasto definito com stock item per la chiusura della nostra finestra.<br>GtkWidget *window, *vbox, *check1, *check2, *check3, *close;<br>gtk_init (&amp;argc, &amp;argv);<br>window = gtk_window_new (GTK_WINDOW_TOPLEVEL);<br>gtk_window_set_title (GTK_WINDOW (window), &#8220;CHECKBUTTONS&#8221;);<br>gtk_container_set_border_width (GTK_CONTAINER (window), 10);<br>gtk_widget_set_size_request (window, 300, 300);<br>\/\/ Definiamo i nostri check buttons impostandogli pure una label.<br>check1 = gtk_check_button_new_with_label (&#8220;Opzione 1&#8221;);<br>check2 = gtk_check_button_new_with_label (&#8220;Opzione 2&#8221;);<br>check3 = gtk_check_button_new_with_label (&#8220;Opzione 3&#8221;);<br>\/\/ in questa maniera disabilito il check2 ed il check3.<br>gtk_widget_set_sensitive (check2, FALSE);<br>gtk_widget_set_sensitive (check3, FALSE);<br>\/\/ Connettiamo al nostro check2 il segnale di toggle (di spunta) e richiamiamo la callback check_toggled. Lo stesso vale per il check3.<br>g_signal_connect (G_OBJECT (check1), &#8220;toggled&#8221;, G_CALLBACK (check_toggled), (gpointer) check2);<br>g_signal_connect (G_OBJECT (check1), &#8220;toggled&#8221;, G_CALLBACK (check_toggled), (gpointer) check3);<br>\/\/ Tasto di chiusura definito come stock item.<br>close = gtk_button_new_from_stock (GTK_STOCK_CLOSE);<br>g_signal_connect_swapped (G_OBJECT (close), &#8220;clicked&#8221;, G_CALLBACK (gtk_widget_destroy), (gpointer) window);<br>vbox = gtk_vbox_new (TRUE, 5);<br>gtk_box_pack_start (GTK_BOX (vbox), check1, FALSE, TRUE, 0);<br>gtk_box_pack_start (GTK_BOX (vbox), check2, FALSE, TRUE, 0);<br>gtk_box_pack_start (GTK_BOX (vbox), check3, FALSE, TRUE, 0);<br>gtk_box_pack_start (GTK_BOX (vbox), close, FALSE, TRUE, 0);<br>gtk_container_add (GTK_CONTAINER (window), vbox);<br>\/\/ Connettiamo il segnale di destroy e delete event alla nostra window.<br>g_signal_connect (G_OBJECT (window), &#8220;destroy&#8221;, G_CALLBACK (destroy), NULL);<br>g_signal_connect (G_OBJECT (window), &#8220;delete_event&#8221;, G_CALLBACK (delete_event), NULL);<br>gtk_widget_show_all (window);<br>gtk_main ();<br>return 0;<br>}<\/p><p>static void destroy (GtkWidget *window, gpointer data)<br>{<br>gtk_main_quit ();<br>}<\/p><p>static gboolean delete_event (GtkWidget *window, GdkEvent *event, gpointer data)<br>{<br>return FALSE;<br>}<\/p><p>\/\/ Funzione che gestisce il toggle (cambio di stato) dei nostri check1,2 e 3.<br>static void check_toggled (GtkToggleButton *A, GtkWidget *B)<br>{<br>\/\/ Se il nostro check \u00e8 attivo&#8230;<br>if (gtk_toggle_button_get_active (A))<br>{<br> \/\/ &#8230;abilito anche l&#8217;altro check passato come g_pointer&#8230;<br> gtk_widget_set_sensitive (B, TRUE);<br>}else{<br> \/\/ &#8230;altrimenti lo disabilito.<br> gtk_widget_set_sensitive (B, FALSE);<br>}<br>}<\/p><\/blockquote>\n\n\n\n<p>Il tutto dovrebbe apparire come in Figura 3, dove abilitando il check1 attiveremo il check2 e il check3.\n&nbsp;\n<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" width=\"304\" height=\"325\" src=\"http:\/\/www.forlex.it\/wp-content\/uploads\/2019\/11\/gtk\/GTK-part4-win-3.png\" alt=\"\" class=\"wp-image-300\" srcset=\"http:\/\/www.forlex.it\/wp-content\/uploads\/2019\/11\/gtk\/GTK-part4-win-3.png 304w, http:\/\/www.forlex.it\/wp-content\/uploads\/2019\/11\/gtk\/GTK-part4-win-3-281x300.png 281w, http:\/\/www.forlex.it\/wp-content\/uploads\/2019\/11\/gtk\/GTK-part4-win-3-100x107.png 100w, http:\/\/www.forlex.it\/wp-content\/uploads\/2019\/11\/gtk\/GTK-part4-win-3-150x160.png 150w, http:\/\/www.forlex.it\/wp-content\/uploads\/2019\/11\/gtk\/GTK-part4-win-3-200x214.png 200w, http:\/\/www.forlex.it\/wp-content\/uploads\/2019\/11\/gtk\/GTK-part4-win-3-300x321.png 300w\" sizes=\"(max-width: 304px) 100vw, 304px\" \/><\/figure>\n\n\n\n<p><strong> I Radio Buttons<\/strong><\/p>\n\n\n\n<p>Un secondo tipo di widget derivato dai toggle buttons sono i radio buttons in effetti i radio buttons derivano, appunto, dai check buttons visti in precedenza.<br>Tutti i radio buttons lavorano a gruppi e solo un radio buttons pu\u00f2 essere attivo (settato) in un gruppo di radio buttons.<\/p>\n\n\n\n<p>Vediamo subito un esempio:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote\"><p>#include &lt;gtk\/gtk.h&gt;<\/p><p>static void destroy (GtkWidget*, gpointer);<br>static gboolean delete_event (GtkWidget*, GdkEvent*, gpointer);<\/p><p>int main (int argc, char *argv[])<br>{<br>\/\/ Definiamo la nostra classica finestra, un container del tipo vertical box, e quattro radio buttons.<br>GtkWidget *window, *vbox, *radio1, *radio2, *radio3, *radio4;<br>gtk_init (&amp;argc, &amp;argv);<br>window = gtk_window_new (GTK_WINDOW_TOPLEVEL);<br>gtk_window_set_title (GTK_WINDOW (window), &#8220;RADIOBUTTON&#8221;);<br>gtk_container_set_border_width (GTK_CONTAINER (window), 10);<br>gtk_widget_set_size_request (window, 300, 200);<br>\/\/ Creiamo il nostro primo radio buttons, con una label a piacere e selezionato di default.<br>radio1 = gtk_radio_button_new_with_label (NULL, &#8220;PRIMO RADIO BUTTON&#8221;);<br>\/\/ Creiamo il radio button 2 che appartiene al gruppo del radio1 precedentemente definito.<br>radio2 = gtk_radio_button_new_with_label_from_widget (GTK_RADIO_BUTTON (radio1), &#8220;SECONDO&#8221;);<br>radio3 = gtk_radio_button_new_with_label_from_widget (GTK_RADIO_BUTTON (radio1), &#8220;TERZO&#8221;);<br>\/\/ Eredita il gruppo definito in radio3. Quindi anche lui sar\u00e0 del gruppo di radio1.<br>radio4 = gtk_radio_button_new_with_label_from_widget (GTK_RADIO_BUTTON (radio3), &#8220;QUARTO&#8221;);<br>vbox = gtk_vbox_new (FALSE, 5);<br>gtk_box_pack_start_defaults (GTK_BOX (vbox), radio1);<br>gtk_box_pack_start_defaults (GTK_BOX (vbox), radio2);<br>gtk_box_pack_start_defaults (GTK_BOX (vbox), radio3);<br>gtk_box_pack_start_defaults (GTK_BOX (vbox), radio4);<br>gtk_container_add (GTK_CONTAINER (window), vbox);<br>g_signal_connect (G_OBJECT (window), &#8220;destroy&#8221;, G_CALLBACK (destroy), NULL);<br>g_signal_connect (G_OBJECT (window), &#8220;delete_event&#8221;, G_CALLBACK (delete_event), NULL);<br>gtk_widget_show_all (window);<br>gtk_main ();<br>return 0;<br>}<\/p><p>static void destroy (GtkWidget *window, gpointer data)<br>{<br>gtk_main_quit ();<br>}<\/p><p>static gboolean delete_event (GtkWidget *window, GdkEvent *event, gpointer data)<br>{<br>return FALSE;<br>}<\/p><\/blockquote>\n\n\n\n<p>Il tutto dovrebbe risultare come in Figura 4:\n&nbsp;\n<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" width=\"304\" height=\"225\" src=\"http:\/\/www.forlex.it\/wp-content\/uploads\/2019\/11\/gtk\/GTK-part4-win-4.png\" alt=\"\" class=\"wp-image-295\" srcset=\"http:\/\/www.forlex.it\/wp-content\/uploads\/2019\/11\/gtk\/GTK-part4-win-4.png 304w, http:\/\/www.forlex.it\/wp-content\/uploads\/2019\/11\/gtk\/GTK-part4-win-4-300x222.png 300w, http:\/\/www.forlex.it\/wp-content\/uploads\/2019\/11\/gtk\/GTK-part4-win-4-100x74.png 100w, http:\/\/www.forlex.it\/wp-content\/uploads\/2019\/11\/gtk\/GTK-part4-win-4-150x111.png 150w, http:\/\/www.forlex.it\/wp-content\/uploads\/2019\/11\/gtk\/GTK-part4-win-4-200x148.png 200w\" sizes=\"(max-width: 304px) 100vw, 304px\" \/><\/figure>\n\n\n\n<p>\n&nbsp;\nSi faccia particolare attenzione che il primo radio buttons viene creato in una certa maniera, mentre il resto, utilizzando una funzione che oltre a definire una label vuole anche sapere a quale gruppo appartiene.<\/p>\n\n\n\n<p><strong>Text Entry<\/strong><\/p>\n\n\n\n<p>I widget text entry, sono degli oggetti che permettono l&#8217;inserimento di dati personali in una singola riga.<br>Questi possono essere usati anche per creare finestre di dialogo utili per l&#8217;inserimento di password o informazioni.<\/p>\n\n\n\n<p>Di seguito creeremo una finestra nella quale verr\u00e0 richiesta la password di un&#8217;utente e la password non sar\u00e0 visibile, ma sar\u00e0 nascosta da un carattere jolly.<\/p>\n\n\n\n<blockquote class=\"wp-block-quote\"><p>#include &lt;gtk\/gtk.h&gt;<\/p><p>static void destroy (GtkWidget*, gpointer);<br>static gboolean delete_event (GtkWidget*, GdkEvent*, gpointer);<\/p><p>int main (int argc, char *argv[])<br>{<br>\/\/ Inizializziamo la nostra finestra un vertical ed un horizontal box due label ed infine il nostro entry.<br>GtkWidget *window, *vbox, *hbox, *label1, *label2, *entry;<br>gchar *str;<br>gtk_init (&amp;argc, &amp;argv);<br>window = gtk_window_new (GTK_WINDOW_TOPLEVEL);<br>gtk_window_set_title (GTK_WINDOW (window), &#8220;PASSWORD&#8221;);<br>gtk_container_set_border_width (GTK_CONTAINER (window), 10);<br>gtk_widget_set_size_request (window, 300, 100);<br>\/\/ Concateniamo la stringa \u201cPassword per\u201d con la nostra variabile d&#8217;ambiente che che contiene il nome dell&#8217;utente connesso. Il tutto poi messo nella nostra label.<br>str = g_strconcat (&#8220;Password per &#8220;, g_get_user_name(),&#8221;?&#8221;, NULL);<br>label1 = gtk_label_new (str);<br>label2 = gtk_label_new (&#8220;Password:&#8221;);<br>\/\/ Ed ecco qui la nostra entry. Settiamo il nostro carattere jolly oltre ad impostare la visibilit\u00e0, cio\u00e8 vedremo alla pressione della nostra password una serie di *.<br>entry = gtk_entry_new ();<br>gtk_entry_set_visibility (GTK_ENTRY (entry), NULL);<br>gtk_entry_set_invisible_char (GTK_ENTRY (entry), &#8216;*&#8217;);<br>hbox = gtk_hbox_new (FALSE, 5);<br>gtk_box_pack_start_defaults (GTK_BOX (hbox), label2);<br>gtk_box_pack_start_defaults (GTK_BOX (hbox), entry);<br>vbox = gtk_vbox_new (FALSE, 5);<br>gtk_box_pack_start_defaults (GTK_BOX (vbox), label1);<br>gtk_box_pack_start_defaults (GTK_BOX (vbox), hbox);<br>gtk_container_add (GTK_CONTAINER (window), vbox);<br>g_signal_connect (G_OBJECT (window), &#8220;destroy&#8221;, G_CALLBACK (destroy), NULL);<br>g_signal_connect (G_OBJECT (window), &#8220;delete_event&#8221;, G_CALLBACK (delete_event), NULL);<br>gtk_widget_show_all (window);<br>gtk_main ();<br>return 0;<br>}<\/p><p>static void destroy (GtkWidget *window, gpointer data)<br>{<br>gtk_main_quit ();<br>}<\/p><p>static gboolean delete_event (GtkWidget *window, GdkEvent *event, gpointer data)<br>{<br>return FALSE;<br>}<\/p><\/blockquote>\n\n\n\n<p>Il tutto compilato dar\u00e0 come risultato la finestra di Figura 5:\n&nbsp;\n<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" width=\"304\" height=\"125\" src=\"http:\/\/www.forlex.it\/wp-content\/uploads\/2019\/11\/gtk\/GTK-part4-win-5.png\" alt=\"\" class=\"wp-image-297\" srcset=\"http:\/\/www.forlex.it\/wp-content\/uploads\/2019\/11\/gtk\/GTK-part4-win-5.png 304w, http:\/\/www.forlex.it\/wp-content\/uploads\/2019\/11\/gtk\/GTK-part4-win-5-300x123.png 300w, http:\/\/www.forlex.it\/wp-content\/uploads\/2019\/11\/gtk\/GTK-part4-win-5-100x41.png 100w, http:\/\/www.forlex.it\/wp-content\/uploads\/2019\/11\/gtk\/GTK-part4-win-5-150x62.png 150w, http:\/\/www.forlex.it\/wp-content\/uploads\/2019\/11\/gtk\/GTK-part4-win-5-200x82.png 200w\" sizes=\"(max-width: 304px) 100vw, 304px\" \/><\/figure>\n\n\n\n<p>\n&nbsp;\nPer tutti i text entry inoltre pu\u00f2 essere settato l&#8217;editabilit\u00e0 del testo la possibilit\u00e0 di selezionarlo oltre ai comandi pi\u00f9 comuni quali il copia incolla ed il taglia.<\/p>\n\n\n\n<p><strong>Spin Buttons<\/strong><\/p>\n\n\n\n<p>Gli spin buttons sono dei widget che permettono la selezione di valori numerici attraverso una barra con&nbsp; tasti dedicati all&#8217;aumento ed alla diminuzione del valore impostato (oppure aumentare o diminuire il valore utilizzando i tasti di page up e page down), vediamo subito un esempio:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote\"><p>#include &lt;gtk\/gtk.h&gt;<\/p><p>static void destroy (GtkWidget*, gpointer);<br>static gboolean delete_event (GtkWidget*, GdkEvent*, gpointer);<\/p><p>int main (int argc, char *argv[])<br>{<br>\/\/ Inizializziamo i nostri oggetti quali lo spin per interi e per float oltre ad un vertical nox come layout..<br>GtkWidget *window, *spin_int, *spin_float, *vbox;<br>\/\/ Mentre qui inizializziamo le variabili che ci faranno da scala come di seguito descritto.<br>GtkAdjustment *integer, *float_pt;<br>gtk_init (&amp;argc, &amp;argv);<br>window = gtk_window_new (GTK_WINDOW_TOPLEVEL);<br>gtk_window_set_title (GTK_WINDOW (window), &#8220;SPINBUTTON&#8221;);<br>gtk_container_set_border_width (GTK_CONTAINER (window), 10);<br>gtk_widget_set_size_request (window, 300, 100);<br>\/* Per ADJUSTMENT abbiamo i seguenti valori, il valore di partenza, il valore minimo, il valore massimo, il passo di incremento, l&#8217;incremento al PgUP\/DOWN e un valore inutile!!! *\/<br>integer = GTK_ADJUSTMENT (gtk_adjustment_new (5.0, 0.0, 10.0, 1.0, 2.0, 2.0));<br>float_pt = GTK_ADJUSTMENT (gtk_adjustment_new (0.5, 0.0, 1.0, 0.1, 0.5, 0.5));<br>\/* Per settare un valore si utilizza il gtk_spin_button_set_value mentre per prelevare il valore impostato con gtk_spin_button_get_value, n.b. il tutto da provare. *\/<br>\/\/ Creiamo il nostro widget sia per l&#8217;intero che per il float.<br>spin_int = gtk_spin_button_new (integer, 1.0, 0);<br>spin_float = gtk_spin_button_new (float_pt, 0.1, 1);<br>vbox = gtk_vbox_new (TRUE, 5);<br>gtk_box_pack_start_defaults (GTK_BOX (vbox), spin_int);<br>gtk_box_pack_start_defaults (GTK_BOX (vbox), spin_float);<br>gtk_container_add (GTK_CONTAINER (window), vbox);<br>g_signal_connect (G_OBJECT (window), &#8220;destroy&#8221;, G_CALLBACK (destroy), NULL);<br>g_signal_connect (G_OBJECT (window), &#8220;delete_event&#8221;, G_CALLBACK (delete_event), NULL);<br>gtk_widget_show_all (window);<br>gtk_main ();<br>return 0;<br>}<\/p><p>static void destroy (GtkWidget *window, gpointer data)<br>{<br>gtk_main_quit ();<br>}<\/p><p>static gboolean delete_event (GtkWidget *window, GdkEvent *event, gpointer data)<br>{<br>return FALSE;<br>}<\/p><\/blockquote>\n\n\n\n<p>Il tutto dovrebbe apparire come segue in Figura 6:\n&nbsp;\n<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" width=\"304\" height=\"125\" src=\"http:\/\/www.forlex.it\/wp-content\/uploads\/2019\/11\/gtk\/GTK-part4-win-6.png\" alt=\"\" class=\"wp-image-294\" srcset=\"http:\/\/www.forlex.it\/wp-content\/uploads\/2019\/11\/gtk\/GTK-part4-win-6.png 304w, http:\/\/www.forlex.it\/wp-content\/uploads\/2019\/11\/gtk\/GTK-part4-win-6-300x123.png 300w, http:\/\/www.forlex.it\/wp-content\/uploads\/2019\/11\/gtk\/GTK-part4-win-6-100x41.png 100w, http:\/\/www.forlex.it\/wp-content\/uploads\/2019\/11\/gtk\/GTK-part4-win-6-150x62.png 150w, http:\/\/www.forlex.it\/wp-content\/uploads\/2019\/11\/gtk\/GTK-part4-win-6-200x82.png 200w\" sizes=\"(max-width: 304px) 100vw, 304px\" \/><\/figure>\n\n\n\n<p><strong>Horizontal &amp; Vertical Scales<\/strong><\/p>\n\n\n\n<p>Gli horizontal ed i vertical scales sono degli oggetti widget che a differenza degli spin sono graficamente degli slides. Inoltre non essendo degli spin limitiamo l&#8217;utente all&#8217;utilizzo delle barre impedendo a all&#8217;utente stesso di inserire un valore numerico.<\/p>\n\n\n\n<p>Vediamo subito un esempio:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote\"><p>#include &lt;gtk\/gtk.h&gt;<\/p><p>static void destroy (GtkWidget*, gpointer);<br>static gboolean delete_event (GtkWidget*, GdkEvent*, gpointer);<\/p><p>int main (int argc, char *argv[])<br>{<br>\/* Inizializzo i miei oggetti tra i quali un scale di interi ed uno float oltre ad un contenitore verticale. *\/<br>GtkWidget *window, *scale_in, *scale_float, *vbox;<br>gtk_init (&amp;argc, &amp;argv);<br>window = gtk_window_new (GTK_WINDOW_TOPLEVEL);<br>gtk_window_set_title (GTK_WINDOW (window), &#8220;SCALES&#8221;);<br>gtk_container_set_border_width (GTK_CONTAINER (window), 10);<br>gtk_widget_set_size_request (window, 200, 100);<br>\/* Si setta il valore minimo, il valore massimo e il passo di avanzamento per lo scales orrizontale. *\/<br>scale_in = gtk_hscale_new_with_range (0.0, 10.0, 1.0);<br>\/* Lo stesso per il float valore minimo, massimo e passo di avanzamento. *\/<br>scale_float = gtk_hscale_new_with_range (0.0, 1.0, 0.1);<br>\/* Setto il decimale da visualizzare se zero visualizzo solo l&#8217;intero, se 1 visualizzo il tipo x.x e cos\u00ec via, 2 visualizzo x.xx etc. *\/<br>gtk_scale_set_digits (GTK_SCALE (scale_in), 0);<br>gtk_scale_set_digits (GTK_SCALE (scale_float), 1);<br>\/* Posizione del valore che assume la barra allo spostamento. *\/<br>gtk_scale_set_value_pos (GTK_SCALE (scale_in), GTK_POS_RIGHT);<br>gtk_scale_set_value_pos (GTK_SCALE (scale_float), GTK_POS_LEFT);<br>\/* gtk_range_get_value() per recuperare il valore della barra. *\/<br>vbox = gtk_vbox_new (TRUE, 5);<br>gtk_box_pack_start_defaults (GTK_BOX (vbox), scale_in);<br>gtk_box_pack_start_defaults (GTK_BOX (vbox), scale_float);<br>gtk_container_add (GTK_CONTAINER (window), vbox);<br>g_signal_connect (G_OBJECT (window), &#8220;destroy&#8221;, G_CALLBACK (destroy), NULL);<br>g_signal_connect (G_OBJECT (window), &#8220;delete_event&#8221;, G_CALLBACK (delete_event), NULL);<br>gtk_widget_show_all (window);<br>gtk_main ();<br>return 0;<br>}<\/p><p>static void destroy (GtkWidget *window, gpointer data)<br>{<br>gtk_main_quit ();<br>}<\/p><p>static gboolean delete_event (GtkWidget *window, GdkEvent *event, gpointer data)<br>{<br>return FALSE;<br>}<\/p><\/blockquote>\n\n\n\n<p>Alla compilazione e di seguito all&#8217;esecuzione del nostro programma avremo il nostro scale come in Figura 7:\n&nbsp;\n<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" width=\"204\" height=\"125\" src=\"http:\/\/www.forlex.it\/wp-content\/uploads\/2019\/11\/gtk\/GTK-part4-win-7.png\" alt=\"\" class=\"wp-image-292\" srcset=\"http:\/\/www.forlex.it\/wp-content\/uploads\/2019\/11\/gtk\/GTK-part4-win-7.png 204w, http:\/\/www.forlex.it\/wp-content\/uploads\/2019\/11\/gtk\/GTK-part4-win-7-100x61.png 100w, http:\/\/www.forlex.it\/wp-content\/uploads\/2019\/11\/gtk\/GTK-part4-win-7-150x92.png 150w, http:\/\/www.forlex.it\/wp-content\/uploads\/2019\/11\/gtk\/GTK-part4-win-7-200x123.png 200w\" sizes=\"(max-width: 204px) 100vw, 204px\" \/><\/figure>\n\n\n\n<p><strong> &nbsp; Il File Chooser Buttons<\/strong><\/p>\n\n\n\n<p>I file chooser button o meglio la finestra di dialogo che permette la selezione di una cartella o di un file permette appunto all&#8217;utente di selezionare con facilit\u00e0 un tipo di file oppure una cartella.<br>Il file chooser buttons \u00e8 cos\u00ec un insieme di widget che permettono quello che \u00e8 stato spiegato precedentemente, vediamo subito come realizzarlo ed impostarlo a seconda delle esigenze.\n&nbsp;\n#include &lt;gtk\/gtk.h&gt;<\/p>\n\n\n\n<p>static void destroy (GtkWidget*, gpointer);<br>static gboolean delete_event (GtkWidget*, GdkEvent*, gpointer);<br>\/\/Funzione per il cambio cartella o dispositivo.<br>static void folder_changed (GtkFileChooser*, GtkFileChooser*);<br>\/\/Funzione per il cambio\/selezione del file.<br>static void file_changed (GtkFileChooser*, GtkLabel*);<\/p>\n\n\n\n<p>int main (int argc, char *argv[])<br>{<br>\/* Inizializzo i miei oggetti. Tra cui i nostri due selettori una etichetta ed infine il conteiner che conterr\u00e0 i nostri oggetti widget. *\/<br>GtkWidget *window, *chooser1, *chooser2, *label, *vbox;<br>\/\/ Inizializziamo inoltre le nostre variabili che definir\u00e0 i nostri filtri.<br>GtkFileFilter *filter1, *filter2;<br>gtk_init (&amp;argc, &amp;argv);<br>window = gtk_window_new (GTK_WINDOW_TOPLEVEL);<br>gtk_window_set_title (GTK_WINDOW (window), &#8220;FILECHOOSER&#8221;);<br>gtk_container_set_border_width (GTK_CONTAINER (window), 10);<br>gtk_widget_set_size_request (window, 400, 200);<br>\/\/ Creeremo la nostra label vuota.<br>label = gtk_label_new (&#8220;&#8221;);<br>\/\/Box per la selezione della cartella o del dispositivo.<br>chooser1 = gtk_file_chooser_button_new (&#8220;Chooser a folder&#8221;, GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER);<br>\/\/Box per la selezione del file.<br>chooser2 = gtk_file_chooser_button_new (&#8220;Chooser a folder&#8221;, GTK_FILE_CHOOSER_ACTION_OPEN);<br>\/\/Connetto il segnale di cambio selezione e gli passo come parametro la selezione del file.<br>g_signal_connect (G_OBJECT (chooser1), &#8220;selection_changed&#8221;, G_CALLBACK (folder_changed), (gpointer) chooser2);<br>\/\/Connetto il segnale di selezione del file al segnale di cambio selezione e gli passo la label come parametro, che prender\u00e0 il nome del file selezionato.<br>g_signal_connect (G_OBJECT (chooser2), &#8220;selection_changed&#8221;, G_CALLBACK (file_changed), (gpointer) label);<br>\/\/Setto la path di partenza per entrambe.<br>gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (chooser1), g_get_home_dir());<br>gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (chooser2), g_get_home_dir());<br>\/\/Creiamo i filtri per i file.<br>filter1 = gtk_file_filter_new ();<br>filter2 = gtk_file_filter_new ();<br>\/\/Definiamo il nome del gruppo dei filtri.<br>gtk_file_filter_set_name (filter1, &#8220;Image files&#8221;);<br>gtk_file_filter_set_name (filter2, &#8220;All files&#8221;);<br>\/\/Estensione dei file da inserire nei gruppi.<br>gtk_file_filter_add_pattern (filter1, &#8220;*.jpg&#8221;);<br>gtk_file_filter_add_pattern (filter1, &#8220;*.png&#8221;);<br>gtk_file_filter_add_pattern (filter2, &#8220;*&#8221;);<br>\/\/Aggiungo i filtri ai box di selezione.<br>gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (chooser2), filter1);<br>gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (chooser1), filter2);<br>vbox = gtk_vbox_new (TRUE, 5);<br>gtk_box_pack_start_defaults (GTK_BOX (vbox), chooser1);<br>gtk_box_pack_start_defaults (GTK_BOX (vbox), chooser2);<br>gtk_box_pack_start_defaults (GTK_BOX (vbox), label);<br>gtk_container_add (GTK_CONTAINER (window), vbox);<br>g_signal_connect (G_OBJECT (window), &#8220;destroy&#8221;, G_CALLBACK (destroy), NULL);<br>g_signal_connect (G_OBJECT (window), &#8220;delete_event&#8221;, G_CALLBACK (delete_event), NULL);<br>gtk_widget_show_all (window);<br>gtk_main ();<br>return 0;<br>}<\/p>\n\n\n\n<p>static void destroy (GtkWidget *window, gpointer data)<br>{<br>gtk_main_quit ();<br>}<\/p>\n\n\n\n<p>static gboolean delete_event (GtkWidget *window, GdkEvent *event, gpointer data)<br>{<br>return FALSE;<br>}<\/p>\n\n\n\n<p>static void folder_changed (GtkFileChooser *A, GtkFileChooser *B)<br>{<br>gchar *folder = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (A));<br>gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (B), folder);<br>}<\/p>\n\n\n\n<p>static void file_changed (GtkFileChooser *A, GtkLabel *B)<br>{<br>gchar *file = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (A));<br>\/\/Stampo la path completa compreso il nome del file.<br>gtk_label_set_text (B, file); <br>}\n&nbsp;\nSe tutto \u00e8 stato scritto e compilato correttamente il tutto dovrebbe dovrebbe apparire come in Figura 8:\n&nbsp;\n<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" width=\"404\" height=\"225\" src=\"http:\/\/www.forlex.it\/wp-content\/uploads\/2019\/11\/gtk\/GTK-part4-win-8.png\" alt=\"\" class=\"wp-image-290\" srcset=\"http:\/\/www.forlex.it\/wp-content\/uploads\/2019\/11\/gtk\/GTK-part4-win-8.png 404w, http:\/\/www.forlex.it\/wp-content\/uploads\/2019\/11\/gtk\/GTK-part4-win-8-300x167.png 300w, http:\/\/www.forlex.it\/wp-content\/uploads\/2019\/11\/gtk\/GTK-part4-win-8-100x56.png 100w, http:\/\/www.forlex.it\/wp-content\/uploads\/2019\/11\/gtk\/GTK-part4-win-8-150x84.png 150w, http:\/\/www.forlex.it\/wp-content\/uploads\/2019\/11\/gtk\/GTK-part4-win-8-200x111.png 200w\" sizes=\"(max-width: 404px) 100vw, 404px\" \/><\/figure>\n\n\n\n<p>\n&nbsp;\nIn questo esempio abbiamo impostato due filtri uno globale assegnato al selettore relativo alla selezione del dispositivo mentre il secondo con il quale era solo possibile visualizzare e selezionare i file di tipo immagine.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Adesso andremo a parlare di quegli oggetti base GTK+ utili all&#8217;utente per interagire con la nostra finestra o interfaccia GTK+. Usare gli STOCK ITEM Iniziamo con il parlare dei tasti gi\u00e0 predefiniti ovvero quei tasti che hanno gi\u00e0 di base &hellip;<\/p>\n<p class=\"read-more\"> <a class=\"\" href=\"http:\/\/www.forlex.it\/index.php\/2019\/11\/03\/interfacce-grafiche-per-i-nostri-programmi-in-gtk-parte-4\/\"> <span class=\"screen-reader-text\">Interfacce grafiche per i nostri programmi in GTK+ &#8211; parte 4 &#8211;<\/span> Read More &raquo;<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[1],"tags":[],"_links":{"self":[{"href":"http:\/\/www.forlex.it\/index.php\/wp-json\/wp\/v2\/posts\/452"}],"collection":[{"href":"http:\/\/www.forlex.it\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.forlex.it\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.forlex.it\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.forlex.it\/index.php\/wp-json\/wp\/v2\/comments?post=452"}],"version-history":[{"count":3,"href":"http:\/\/www.forlex.it\/index.php\/wp-json\/wp\/v2\/posts\/452\/revisions"}],"predecessor-version":[{"id":561,"href":"http:\/\/www.forlex.it\/index.php\/wp-json\/wp\/v2\/posts\/452\/revisions\/561"}],"wp:attachment":[{"href":"http:\/\/www.forlex.it\/index.php\/wp-json\/wp\/v2\/media?parent=452"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.forlex.it\/index.php\/wp-json\/wp\/v2\/categories?post=452"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.forlex.it\/index.php\/wp-json\/wp\/v2\/tags?post=452"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}