# Come creare GUI in GTK portabili su Windows

## canduc17

(Versione in Inglese!!!)

Dovendo fare un programmino su Windows con una semplice GUI, ho pensato: perchè non farlo con solo software open?

Mi sarebbe piaciuto avere qualcosa di portabile, compilabile sia su Linux che su Windows: così mi messo a fare diversi esperimenti.

Ecco alcune note su quello che ho tirato fuori...spero possa essere utile a qualcuno.

Ho pensato di sviluppare il tutto in GTK+, le librerie di Gnome scritte in C portabili anche su Windows.

Ho preferito però utilizzarle indirettamente attraverso gtkmm, un wrapper che permette di utilizzare le GTK programmando in C++ invece che in C, avvalendosi di una sintassi molto più snella. Questa interfaccia è usata da progetti open molto importanti come Inkscape ed Ardour.

Come compilatore non potevo che scegliere gcc, del quale esiste un porting per Windows all'interno del pacchetto MinGW.

Questo "Minimalistic GNU for Windows" offre anche una shell UNIX, molto comoda soprattutto per compilare da riga di comando.

Poi l'IDE: ho optato per Code::Blocks, anch'esso avente ovviamente una versione per Windows.

Riassumendo, ho usato i seguenti pacchetti, scaricati dai relativi siti:mingw-get-inst-20100909.exe (gcc, shell unix, ssh, vim editor, make...)codeblocks-10.05-setup.exe (la versione senza MinGW incorporata)gtkmm-win32-devel-2.22.0-1.exe (che include il porting delle librerie GTK+)

MinGW

Lanciate l'installer reperibile all'url postato sopra e scegliete un path di installazone privo di spazi (il C:\MinGW di default va benissimo), altrimenti il pacchetto può avere dei problemi.

Scegliete i compilatori C, C++ e MSYS (la shell UNIX): l'installer scaricherà ed installerà ciò che gli avete detto.

Aggiungete infine la stringa C:\MinGW\bin; alla variabile d'ambiente Path (su Windows 7 la trovate in Control Panel --> System and Security --> System --> 

Advanced System Settings --> Environment Variables --> System Variables).

Aprite MSYS e digitate

```
gcc --version
```

Se il comando viene riconosciuto e vi viene restituito il numero di versione, l'installazione è andata a buon fine e potrete compilare come sulla vostra Gentoo Box: il prodotto finale sarà però un .exe eseguibile su Windows.

gtkmm

Grazie all'installer descritto sopra, installate tutti i componenti disponibili in C:\gtkmm e controllate che nella variabile d'ambiente Path sia stata aggiunta automaticamente la stringa C:\gtkmm\bin.

Ora possiamo fare il nostro primo esperimento.

Prendiamo come esempio i file che trovate qui, all'interno della documentazione di gtkmm: esso si avvale di Glade e GTK::Builder.

In pratica, invece di "disegnare" l'interfaccia mediante del codice C++, è possibile crearla con un programma a finestre (Glade) il quale produce un file xml che descrive l'interfaccia; questa viene poi caricata a runtime ed "interpretata" da GTK::Builder. Utilizzando questi strumenti, la stesura ed il debug della GUI è molto più veloce e richiede meno codice C++.

Abbiamo quindi due file, main.cc (il programma vero e proprio) e basic.ui (il file xml che descrive l'interfaccia). Scriviamo poi un semplice Makefile:

```
CC=g++

FLAGS=-Wall -g -O3 -DDEBUG

GTKMMFLAGS=`pkg-config gtkmm-2.4 --cflags --libs`

#Executable name:

TARGET=gtkmmExample

all: main.cc

   $(CC) $(FLAGS) *.cc -o $(TARGET) $(GTKMMFLAGS)

clean:

   rm -f gtkmmExample
```

e salviamo questi tre file in una directory raggiungibile da MSYS, ad esempio C:\MinGW\msys\1.0\home\utente\esempio.

Aprite dal menu Start la MinGW Shell (MSYS), entrate nella directory "esempio" e lanciate make: dopo la compilazione, dovrebbe essere stato prodotto l'eseguibile gtkmmExample.exe, lanciabile con un semplice doppio click dal File Manager di Windows.

Code::Blocks

Per programmi semplici potete usare Vim installato con MinGW, oppure un altro editor open per Windows come SciTE (che io consiglio caldamente). Se i vostri progetti sono belli corposi, invece, un IDE come Code::Blocks è più indicato.

Utilizzate l'installer descritto sopra: esso troverà gcc installato con MinGW e lo imposterà automaticamente come compilatore di default.

Per compilare, però, dovete permettere ai progetti che create di raggiungere le librerie gtkmm. Vediamo come farlo, riproponendo l'esempio sopra.

Aprite Code::Blocks, create un progetto vuoto di tipo console selezionando Console Application --> Empty Project e salvatelo in una directory come C:\Users\utente\Desktop\esempio.

Copiate i file main.cc e basic.ui in questa directory: per aggiungerli cliccate con il tasto destro sul nome del progetto e dal menu constestuale selezionate "Add Files...".

Andate in Project --> Build options --> Compiler settings --> Other options ed incollate la stringa 

```
`pkg-config --cflags gtkmm-2.4`
```

Andate poi in Project --> Build options --> Linker settings --> Other linker options ed incollate la stringa

```
`pkg-config --libs gtkmm-2.4`
```

Queste operazioni vanno ripetute 2 volte, sia per il build target "Debug" che per quello "Release" (li selezionate in alto a sinistra nella finestra di Build Options).

Ora con il tasto a forma di ingranaggio e play verde potete compilare ed eseguire il vostro esempietto.

Questo è quanto: ora potete ottenere la stessa versione di un programma con interfaccia grafica sia su Linux che su Windows!

Buon divertimento!!!

:::::::::: EDIT ::::::::::

Alcune note utili, dopo qualche esperienza in più:Inclusione glade file

Se non volete dover portarvi dietro il file glade assieme al vostro eseguibile per farlo funzionare, un modo molto semplice è quello di includerlo all'interno del codice C++, definendolo come una lunga stringa di caratteri.

Ad esempio, all'inizio del file possiamo fare questa dichiarazione globale:

```
char glade_xml[]="<?xml version=\"1.0\"?>\

<interface>\

  <requires lib=\"gtk+\" version=\"2.16\"/>\

...

<signal name=\"insert_text\" handler=\"on_textbuffer1_insert_text\" object=\"casa\" after=\"yes\"/>\

  </object>\

</interface>";
```

e chiamare questo array con

```
// Dentro alla funzione main():

Gtk::Main kit(argc, argv);

Glib::RefPtr<Gtk::Builder> refBuilder = Gtk::Builder::create();

refBuilder->add_from_string(glade_xml); 
```

L'unico problema è che prima dell'iclusione, bisogna fare l'escape di tutti i caratteri tipo " o ??? e si deve mettere una \ alla fine di ogni riga.

Per far questo comodamente diamo il nostro glade file in pasto a sed:

```
sed -e 's/"/\\"/g' basic.ui | sed -e 's/???/?\\?\\?/g' | sed -e 's/$/\\/g'
```

Linking statico librerie

Se provate a spostare il vostro .exe compilato con Code::Blocks su una macchina windows che non ha l'ambiente di sviluppo descritto sopra, il vostro programma non partirà, lamentando la mancanza di 2 librerie dinamiche: libgcc_s_dw2-1.dll e libstdc++-6.dll.

Per evitare questo problema bisogna includere staticamente le dll nell'eseguibile: aprite il progetto di Code::Blocks ed andate in Project --> Build options --> Linker settings --> Other linker options ed aggiungete sia alla versione Debug che Release le seguenti righe

```
-static-libgcc

-static-libstdc++
```

Sviluppo con Code::Blocks: esecuzione senza console

Sempre in Code::Blocks, mentre per la versione Debug del vostro eseguibile può tornare comoda una console che si apre dietro la vostra GUI, nella versione Release è veramente fastidiosa.

Per eliminarla andate in Project --> Properties --> Build Targets e per la versione Release, nel menu a tendina Type scegliete GUI application.

----------

## ago

sarebbe stata una bella cosa farlo in qt4  :Smile: 

----------

## Onip

 *ago wrote:*   

> sarebbe stata una bella cosa farlo in qt4 

 

che senso ha un commento del genere?

----------

## .:deadhead:.

 *Onip wrote:*   

> che senso ha un commento del genere?

 Informa i futuri lettori che esiste un'altra libreria open & production ready usata per prodotti consumer (opera, skype giusto per citarne due) e ben documentata, per scrivere applicazioni multipiattaforma in C++.

----------

