# Glade FAQ

Copyright © 2000 by Damon Chaplin

Copyright © 2001 by Fabrizio Stefani (traduzione italiana)

Questa è una lista delle più gettonate domande ricorrenti su `Glade`, il costruttore di interfacce utente Gtk+/GNOME.

1. Informazioni generali su Glade
  Q: Quale documentazione è disponibile per Glade?
  Q: Esiste codice d'esempio?
  Q: Devo usare una qualche licenza particolare per il codice C generato con Glade?
2. Creare una interfaccia utente con Glade
  Q: Quando aggiungo un widget ad una finestra, questo me la occupa interamente e non posso aggiungere nessun altro widget.
  Q: Come faccio a cambiare i colori di un widget (ad es. a colorare di rosso una label)?
  Q: Come aggiungo un disegno ad un pulsante?
  Q: Come faccio ad aggiungere più di un widget (dello stesso tipo) alla volta?
  Q: Tutte le volte che uso una finestra di scorrimento ottengo il seguente avvertimento: Gtk-WARNING **: gtk_scrolled_window_add(): cannot add non scrollable widget use gtk_scrolled_window_add_with_viewport() instead
  Q: Quali formati grafici sono supportati da Glade?
  Q: Come si fa ad aggiungere un gestore di segnale?
3. Compilare il codice C generato da Glade
  Q: Come faccio a compilare il codice generato da Glade?
  Q: Mi dà questo errore: aclocal: configure.in: 10: macro `AM_PATH_GTK' not found in library
  Q: Mi dà questo errore: ** CRITICAL **: file glade_gnome.c: line 939 (glade_gnome_write_menu_item_source): assertion `source_buffer != NULL' failed.
4. Usare il codice C generato da Glade
  Q: Quali sono i file scritti da Glade?
  Q: Quali file possono essere modificati tranquillamente dallo sviluppatore e quali invece vengono sovrascritti?
  Q: Come faccio ad aggiungere al progetto i miei file sorgenti?
  Q: Come faccio ad aggiungere una libreria al progetto?
  Q: Come ottengo un puntatore ad un widget da dentro un gestore di segnale?
  Q: Come ottengo un puntatore ad un widget di un'altra finestra?
  Q: Come ottengo il valore di un GtkOptionMenu?
  Q: Come faccio a far chiamare una funzione a GtkOptionMenu quando cambia?
  Q: Come mi connetto ai segnali GtkAdjustment?
  Q: Come faccio ad aggiungere delle righe ad una GtkCList prima che la finestra venga disegnata?

### 1. Informazioni generali su Glade

Q: Quale documentazione è disponibile per Glade?

A: Nella versione GNOME di Glade sono disponibili la Guida Quick-Start, il Manuale e le FAQ, direttamente dal menu Aiuto. Sfortunatamente questi ancora non coprono tutti gli aspetti riguardanti l'uso di Glade.

Sul web sono reperibili alcuni altri documenti:

La guida Spagnola: tigre.aragon.unam.mx/m3d/links_es.htm

La guida Italiana: digilander.iol.it/robang/glade

Non credo che ci siano libri che trattano specificatamente di Glade; comunque ho visto un capitolo su Glade in un libro della Wrox press dedicato agli sviluppatori Linux.

Aggiungerò, sulla home page di Glade glade.gnome.org, link riguardanti la documentazione, non appena disponibili.

Q: Esiste codice d'esempio?

A: Glade include un semplice editor di testo, come esempio, nella directory examples/editor. Se avete installato un pacchetto binario di Glade (ad es. un RPM), tali file potrebbero essere stati installati in /usr/doc/glade-X.X.X. Se non riuscite a trovarlo scaricate il pacchetto tar da glade.gnome.org.

Il sito web contiene dei link a diverse applicazioni create usando Glade. Queste potrebbero contenere utile codice d'esempio. Vedi la pagina 'Applications' su glade.gnome.org.

Q: Devo usare una qualche licenza particolare per il codice C generato con Glade?

A: No. Sei libero di usare qualsiasi licenza tu voglia per il codice C generato da Glade.

Comunque, nello spirito del software libero, ti incoraggiamo ad usare la licenza GPL o la LGPL.

### 2. Creare una interfaccia utente con Glade

Q: Quando aggiungo un widget ad una finestra, questo me la occupa interamente e non posso aggiungere nessun altro widget.

A: Non è un bug di `Glade`! In GTK+ si usano dei contenitori per disporre i widget. I contenitori più usati si trovano in fondo alla finestra principale della palette. Prova ad aggiungere alla finestra un riquadro verticale. Ora aggiungi una tabella in una delle divisioni del riquadro verticale. Adesso hai afferrato l'idea?

Se proprio vuoi posizionare i widget in specifiche coordinate, prova il contenitore a Posizioni fisse. Però questa tecnica è sconsigliata perché le tue finestre (normali o di dialogo) non avranno un bel aspetto quando vengono ridimensionate; e se poi traduci il testo delle etichette e dei pulsanti in altre lingue, le scritte potrebbero non entrarci.

Q: Come faccio a cambiare i colori di un widget (ad es. a colorare di rosso una label)?

A: Puoi usare i file rc GTK+ standard per impostare i colori e i font dei tuoi widget. Se in Glade abiliti l'opzione 'Imposta nomi dei widget', risulterà più semplice fare riferimento ai tuoi widget, visto che potrai chiamarli per nome. Vedi la documentazioni sulle risorse di GTK+ presso developer.gnome.org/doc/API/gtk/index.html.

Puoi anche cambiare lo stile di un widget all'interno del tuo codice chiamando gtk_widget_modify_style(); ad es:

      GdkColor red = { 0, 65535, 0, 0 };
      GtkRcStyle *rc_style = gtk_rc_style_new ();
      rc_style->fg[GTK_STATE_NORMAL] = red;
      rc_style->color_flags[GTK_STATE_NORMAL] |= GTK_RC_FG;
      gtk_widget_modify_style (widget, rc_style);
      gtk_rc_style_unref (rc_style);

Q: Come aggiungo un disegno ad un pulsante?

A: Crea un pulsante e seleziona `Rimuovi etichetta` dal menu a comparsa. Ora puoi aggiungere al pulsante qualsiasi widget tu voglia; ad es. un riquadro orizzontale con dentro un disegno e una etichetta (`Glade` in futuro potrebbe rendere questa operazione ancora più semplice).

Q: Come faccio ad aggiungere più di un widget (dello stesso tipo) alla volta?

A: Tieni premuto il tasto 'Control' quando selezioni il widget nella Palette. Rimarrà selezionato finché non scegli un widget, oppure il Selettore.

Q: Tutte le volte che uso una finestra di scorrimento ottengo il seguente avvertimento: Gtk-WARNING **: gtk_scrolled_window_add(): cannot add non scrollable widget use gtk_scrolled_window_add_with_viewport() instead

A: Puoi tranquillamente ignorarlo. È emesso da GTK+ per ricordare ai programmatori di aggiornare il proprio codice; ciò perché il comportamento delle finestre di scorrimento è cambiato abbastanza fra GTK+ 1.0 e GTK+ 1.2. Ma il codice di `Glade` è a posto. L'avvertimento non dovrebbe apparire nella tua applicazione finale.

Q: Quali formati grafici sono supportati da Glade?

A: Se stai creando una applicazione GTK+ allora i tuoi disegni devono essere in formato XPM (GTK+ 2.0 includerà la libreria gdk-pixbuf e quindi supporterà molti più formati grafici).

Se stai creando una applicazione GNOME allora puoi usare la maggior parte dei formati grafici. Comunque il formato PNG è quello da preferire per la maggior parte della grafica, tipo le icone.

Puoi convertire le immagini nei vari formati usando il programmma di grafica GIMP, oppure l'utility 'convert' del pacchetto ImageMagick.

Q: Come si fa ad aggiungere un gestore di segnale?

A: Segui questi passi:

- Seleziona il widget a cui vuoi aggiungere il gestore.

- Seleziona la scheda 'Segnali' nella finestra dell'editor delle proprietà.

- Clicca sul pulsante '...' che si trova a destra del campo 'Segnale:'. Apparirà una finestra con l'elenco dei segnali emessi dal widget selezionato.

- Nella finestra appena comparsa scegli a quale segnale vuoi connettere un gestore e premi il pulsante 'OK'.

- Glade genera automaticamente un nome, per la funzione del gestore di segnale nel campo 'Gestore:', ma sei libero di cambiarlo, se preferisci.

- Clicca sul pulsante 'Aggiungi' per aggiungerlo alla lista dei gestori di segnale di questo widget.

Quando generi il sorgente C, nel file callbacks.c, verrà scritta una funzione vuota per il gestore di segnale. Puoi aggiungere il tuo codice a questa funzione.

### 3. Compilare il codice C generato da Glade

Q: Come faccio a compilare il codice generato da Glade?

A: Per compilare il codice C generato da Glade ti servono `automake` >= 1.4 e `autoconf` >= 2.13. Se hai attivato il supporto per `gettext` allora ti serve anche `gettext` >= 0.10.35. Per dei riferimenti sull'argomento vedi la sezione Requirements nel file `README`.

Lancia ./autogen.sh nella directory base del progetto per eseguire `automake`, `autoconf` e le relative utilità per generare i `Makefile`. Passagli tutte le opzioni che vuoi siano passate al configure; ad es. dài ./autogen.sh --prefix /usr/local/gnome.

Poi lancia il make per compilare l'applicazione.

Nota che per le applicazioni GNOME devi dare anche un make install di modo che i pixmap vengano installati appropriatamente. Se non lo fai l'applicazione funzionerà lo stesso, ma non vedrai i pixmap.

Q: Mi dà questo errore: aclocal: configure.in: 10: macro `AM_PATH_GTK' not found in library

A: Significa che non è possibile trovare il file `gtk.m4` (`gtk.m4` è un insieme di macro m4 che vengono installate come parte di GTK+ e sono usate per compilare i programmi che usano GTK+). `aclocal` (che fa parte di `automake`) ricerca queste macro per aggiungerle ad `aclocal.m4` nella directory principale del tuo programma.

Per scoprire dove è stato installato GTK+ lancia gtk-config --prefix. Il file `gtk.m4` dovrebbe trovarsi nella sottodirectory `share/aclocal`. Per sapere qual è la directory che sta usando `aclocal` lancia aclocal --print-ac-dir.

Dovresti aggiungere la directory in cui sono installati i file m4 GTK+ alla variabile d'ambiente `ACLOCAL_FLAGS`; cioè se i file m4 GTK+ si trovano in `/usr/local/share/aclocal`, allora aggiungi export ACLOCAL_FLAGS="-I /usr/local/share/aclocal/" al tuo `$HOME/.profile`.

Q: Mi dà questo errore: ** CRITICAL **: file glade_gnome.c: line 939 (glade_gnome_write_menu_item_source): assertion `source_buffer != NULL' failed.

A: Stai tentando di usare i menu di Gnome in una applicazione che è solo GTK+. Edita tutti i menu del tuo progetto ed assicurati che la proprietà "Oggetto Stock" sia impostata a "Nessuno" in tutte le voci di menu.

### 4. Usare il codice C generato da Glade

Q: Quali sono i file scritti da Glade?

A: Ecco un elenco dei file che vengono scritti di solito; se hai cambiato le opzioni del progetto alcuni nomi potrebbero essere diversi.

`autogen.sh` . Uno script che lancia nel giusto ordine `automake`, `autoconf` e i programmi correlati, facilitando enormemente la compilazione dell'applicazione. Devi passargli tutti gli argomenti che vuoi siano passati a `configure`. Dopo averlo eseguito puoi dare make per compilare l'applicazione.

`configure.in` . È lo script standard passato ad `autoconf` per generare lo script di configurazione.

`Makefile.am` . Contiene le direttive standard di compilazione, passate ad automake per generare il `Makefile.in`, che lo script configure trasforma nel `Makefile`.

`acconfig.h` . Contiene alcune macro che vengono impostate dallo script configure e aggiunte al file header `config.h` (che deve essere il primo file di cui si fa #include in tutti i tuoi file sorgenti). La maggior parte di queste macro servono per il supporto a gettext (ENABLE_NLS, HAVE_CATGETS, HAVE_GETTEXT, HAVE_LC_MESSAGES, HAVE_STPCPY), HAVE_LIBSM serve a Gnome (ma non danneggia le applicazioni GTK+) e solo alcune sono aggiunte da `Glade` (PACKAGE_LOCALE_DIR, PACKAGE_DATA_DIR, PACKAGE_SOURCE_DIR).

`stamp-h.in` . Usata come timestamp (data/ora) da `automake`, per ricompilare alcuni dei file generati.

`AUTHORS`, `ChangeLog`, `NEWS`, `README` . Questi file sono tutti inizialmente vuoti, vengono creati solo per aderire alle convenzioni GNU.

`src/Makefile.am` . Il file standard di make.

`src/main.c` . Contiene la funzione `main`() che creerà per te tutte le finestre (normali e di dialogo).

`src/interface.h` . Dichiarazioni delle funzioni che puoi chiamare per creare le finestre (normali e di dialogo) che sono state preparate in `Glade`.

`src/interface.c` . Il codice per creare le finestre (normali e di dialogo) e tutti i widget.

`src/callbacks.h` . Dichiarazioni delle funzioni di callback e dei gestori di segnale che scriverai.

`src/callbacks.c` . Le funzioni di callback e i gestori di segnale.

`src/support.h` . Dichiarazioni di alcune funzioni di supporto, compresa `lookup_widget`() che puoi usare per ottenere dei puntatori ai widget.

`src/support.c` . Le funzioni di supporto.

Se è abilitato il supporto per `gettext` viene creata la directory `po` con un `POTFILES.in` ed un `ChangeLog` separato. `POTFILES.in` elenca i file sorgenti che contengono delle stringhe traducibili e dovresti aggiungere qui tutti i file sorgente che crei.

Per i progetti GNOME viene aggiunta anche la directory `macros`, che contiene tutte le macro m4 usate per compilare il progetto (veramente queste avrebbero dovuto essere installate come parte di GNOME, ma sfortunatamente ciò non è stato fatto in GNOME 1.0.x; si spera che questa cosa venga corretta in una futura versione di GNOME, al che questa directory non sarà più necessaria).

Dopo aver compilato il progetto, se cambi le opzioni `Supporto per Gnome` o `Supporto per gettext`, allora dovrai aggiornare alcuni dei file compilati, come `configure.in` e `Makefile.am`. La soluzione migliore probabilmente è di cambiare la directory del progetto nella finestra di dialogo Opzioni del progetto e ricompilare il progetto da zero. Tuttavia così facendo dovrai ricopiare tutto il codice che avevi, eventualmente, aggiunto per gestire i segnali. Un'alternativa è quella di cancellare `autogen.sh`, `configure.in`, `Makefile.am`, `src/Makefile.am`, `src/main.c` e ricrearli usando `Glade`. Ma se avevi fatto dei cambiamenti in tali file allora dovrai rifarli (si spera che in futuro `Glade` gestisca meglio questo problema).

Q: Quali file possono essere modificati tranquillamente dallo sviluppatore e quali invece vengono sovrascritti?

A: `Glade` non sovrascrive quasi nessuno dei file. Esso ricreerà i file necessari per la compilazione, se non esistono già (e se è attivata la corrispondente opzione di progetto).

I file che `Glade` sovrascrive sono: `interface.h`, `interface.c`, `support.h` e `support.c` (sebbene, nel tuo progetto, potresti averli chiamati diversamente, cambiandoli nella finestra di dialogo Opzioni del progetto).

Tali file hanno tutti un avvertimento in cima che dice "DO NOT EDIT" (NON MODIFICARE).

Se hai aggiunto, o aggiornato, un qualunque gestore di segnale, esso verrà accodato nei file `callbacks.h` e `callbacks.c`. In questo modo qualunque codice di callback tu avessi già aggiunto è completamente al sicuro! Se hai cambiato nome ad una funzione di gestione di segnale allora sta a te cancellare la vecchia versione e copiare il codice in quella nuova.

Q: Come faccio ad aggiungere al progetto i miei file sorgenti?

A: Aggiungili, compresi i file header, in `src/Makefile.am`, nella variabile ``project1`_SOURCES` (dove `project1` è il nome del tuo progetto).

Se usi `gettext` probabilmente vorrai aggiungere i file sorgente anche in `po/POTFILES.in`; di modo che le stringhe possano essere tradotte.

Q: Come faccio ad aggiungere una libreria al progetto?

A: Nel file configure.in del tuo progetto, devi aggiungere un controllo per verificare che CPPFLAGS e LIBS siano aggiornati in modo da tener conto della libreria (la variabile CPPFLAGS deve contenere tutti i flag -I da passare al preprocessore C, mentre la variabile LIBS deve contenere le opzioni -l e -L da passare al linker).

Autoconf fornisce delle macro come AC_CHECK_HEADER e AC_CHECK_LIB che possono essere usate per controllare generici header e librerie.

Molte librerie GTK+ e Gnome forniscono uno script di configurazione, tipo gtk-config, che emettono i flag CPPFLAGS e LIBS necessari.

Ad esempio, libxml fornisce lo script xml-config che puoi usare in questo modo:

      dnl Get libxml flags & libs
      AC_PATH_PROG(xml_config, xml-config)
      if test "x$xml_config" = "x"; then
        AC_MSG_ERROR([*** xml-config not found.])
      fi

      XML_CFLAGS=`$xml_config --cflags 2>/dev/null`
      XML_LIBS=`$xml_config --libs 2>/dev/null`
      CPPFLAGS="$CPPFLAGS $XML_CFLAGS"
      LIBS="$LIBS $XML_LIBS"

Assicurati di mettere il tuo configure.in di test prima della chiamata di AC_OTUPUT.

Q: Come ottengo un puntatore ad un widget da dentro un gestore di segnale?

A: Usa la funzione `lookup_widget`() (la puoi trovare in `support.c`).

Devi passargli un puntatore ad un qualsiasi widget di una finestra e il nome del widget che vuoi ottenere. Di solito, da dentro i gestori di segnale, puoi usare il primo argomento del gestore di segnale come primo parametro di `lookup_widget`(); ad es:

    void
    on_button1_clicked                     (GtkButton       *button,
                                            gpointer         user_data)
    {
      GtkWidget *entry1;

      entry1 = lookup_widget (GTK_WIDGET (button), "entry1");

      ...
    }

Nota che ciò non funzionerà se stai usando libglade. Il codice corrispondente per libglade è:

    void
    on_button1_clicked                     (GtkButton       *button,
                                            gpointer         user_data)
    {
      GladeXML* xml;
      GtkWidget* entry1;

      xml = glade_get_widget_tree (GTK_WIDGET (button1));
      entry1 = glade_xml_get_widget (xml, "entry1");

      ...
    }

Q: Come ottengo un puntatore ad un widget di un'altra finestra?

A: Devi tenere traccia dei puntatori a tutte le tue finestre di primo livello. Nelle applicazioni più semplici, per memorizzare tali puntatori puoi usare delle variabili globali.

Nelle applicazioni più complesse puoi usare `gtk_object_set_data`() e le funzioni correlate per memorizzare un puntatore ad una finestra contenuta in un'altra finestra. Ad esempio, se vuoi creare una finestra di dialogo che necessita di accedere ai widget della finestra principale, puoi fare così:

      dialog = create_dialog1 ();  /* Chiama la funzione generata da Glade. */
      gtk_object_set_data (GTK_OBJECT (dialog), "main_window", main_window);

Poi, quando ti serve di accedere alla finestra principale dal codice della finestra di dialogo, puoi fare così:

      main_window = gtk_object_get_data (GTK_OBJECT (dialog), "main_window");

Devi fare attenzione e assicurarti che il puntatore sia sempre valido. Se la finestra a cui punta viene distrutta, non devi più usare quel puntatore, altrimenti la tua applicazione potrebbe collassare.

Q: Come ottengo il valore di un GtkOptionMenu?

A: Per ottenere la voce di menu correntemente selezionata, chiama `gtk_menu_get_active`() con il menu GtkOptionMenu. Per trovare il suo indice nel menu puoi usare `g_list_index`():

    void
    on_button1_clicked                     (GtkButton       *button,
                                            gpointer         user_data)
    {
      GtkWidget *option_menu, *menu, *active_item;
      gint active_index;

      option_menu = lookup_widget (GTK_WIDGET (button), "optionmenu1");
      menu = GTK_OPTION_MENU (option_menu)->menu;
      active_item = gtk_menu_get_active (GTK_MENU (menu));
      active_index = g_list_index (GTK_MENU_SHELL (menu)->children, active_item);

      g_print ("Active index: %i\n", active_index);
    }

Q: Come faccio a far chiamare una funzione a GtkOptionMenu quando cambia?

A: Al momento `Glade` non ha un modo per aiutarti a farlo, ma puoi farlo manualmente.

Quando crei la finestra prendi il menu opzioni e connettilo al segnale "deactivate" emesso dal suo menu:

      window1 = create_window1 ();
      option_menu = lookup_widget (window1, "optionmenu1");
      gtk_signal_connect (GTK_OBJECT (GTK_OPTION_MENU (option_menu)->menu),
                          "deactivate", GTK_SIGNAL_FUNC (on_option_selected),
                          NULL);

Poi aggiungi un gestore in `callbacks.c`. Puoi ottenere l'indice della voce selezionata nel modo spiegato nella domanda precedente:

    static void
    on_option_selected (GtkMenuShell *menu_shell,
                        gpointer data)
    {
      GtkWidget *active_item;
      gint item_index;

      active_item = gtk_menu_get_active (GTK_MENU (menu_shell));
      item_index = g_list_index (menu_shell->children, active_item);

      g_print ("In on_option_selected active: %i\n", item_index);
    }

Q: Come mi connetto ai segnali GtkAdjustment?

A: Al momento `Glade` non lo supporta; ma puoi farlo manualmente, in modo simile a quanto visto nella domanda 3.6.

Quando crei la finestra prendi un puntatore al widget che contiene l'adattamento e connettilo al segnale "changed" o "value_changed":

      window1 = create_window1 ();
      hscale = lookup_widget (window1, "hscale1");
      gtk_signal_connect (GTK_OBJECT (GTK_RANGE (hscale)->adjustment),
                          "changed", GTK_SIGNAL_FUNC (on_adjustment_changed),
                          NULL);

Q: Come faccio ad aggiungere delle righe ad una GtkCList prima che la finestra venga disegnata?

A: Dopo aver creato la finestra, usando la funzione 'create' generata da Glade, usa `lookup_widget`(), per ottenere un puntatore al widget GtkCList, e aggiungi le righe volute. Ad es:

      GtkWidget *window, *clist;
      gchar *row[2];		/* La nostra GtkCList ha solo 2 colonne. */

      window = create_window1 ();
      clist = lookup_widget (window, "clist1");

      row[0] = "Ciao";
      row[1] = "Mondo";
      gtk_clist_append (GTK_CLIST (clist), row);

      row[0] = "Seconda";
      row[1] = "Riga";
      gtk_clist_append (GTK_CLIST (clist), row);

      gtk_widget_show (window1);

Questa FAQ è stata scritta da Damon Chaplin (`<damon@ximian.com>`). Per favore, invia commenti e suggerimenti riguardanti questo manuale all'autore. Per maggiori informazioni su `Glade`, o sulle mailing list riguardanti `Glade`, visita la pagina web di Glade.

Traduzione italiana di Fabrizio Stefani (`<fstef@it.gnome.org>`). Per favore, invia commenti e suggerimenti riguardanti questa traduzione al suddetto indirizzo.