Visualizzazione post con etichetta programmare. Mostra tutti i post
Visualizzazione post con etichetta programmare. Mostra tutti i post

giovedì 22 dicembre 2016

Iniziare a programmare con SDL 2 su Linux - parte 2


Nella prima parte di questo tutorial abbiamo visto come installare tutti gli strumenti di sviluppo e abbiamo creato il nostro primo programma sfruttando la libreria SDL 2. In questa seconda parte approfondiremo meglio l'utilizzo di g++ e valgrind, inoltre miglioreremo il nostro SDL Hello World.

Per tutti coloro che sono nuovi utenti del mondo Linux o che comunque non hanno esperienza nell'invocazione del compilatore g++ ho pensato di fare un po' di chiarezza sulla sintassi di questo comando.

La sintassi più semplice è
$ g++ [file sorgente]

L'eseguibile avrà il nome di default a.out.
Per specificare il nome dell'eseguibile basta aggiungere l'opzione -o [nome eseguibile], quindi
$ g++ [file sorgente] -o [nome eseguibile]

Se ci sono più file sorgenti basta elencarli
$ g++ [file sorgente 1] [file sorgente 2] -o [nome eseguibile]

Per finire, se dobbiamo utilizzare una libreria, come SDL 2 nel nostro caso, dobbiamo comunicarlo al linker tramite l'opzione -l (elle minuscola) seguita dal nome della libreria senza spazi.
$ g++ [file sorgenti] -o [nome eseguibile] -l[nome libreria]

Per la libreria SDL 2 scriveremo -lSDL2

Bene, questo è quanto abbiamo visto finora nella prima parte del tutorial, ma avrete notato che, quando la lista dei file sorgente aumenta, invocare g++ diventa decisamente scomodo.
Per semplificare il tutto possiamo utilizzare il comando make.

Il funzionamento di make è molto semplice, dobbiamo creare un file di testo dove forniremo tutte le informazioni necessarie per la compilazione, quali il compilatore da invocare, la lista dei file sorgente, le opzioni da passare al compilatore, ecc...
Una volta preparato il file chiamato Makefile, basterà invocare make e questo invocherà g++ per noi.
Questo è un esempio di Makefile per compilare il nostro SDL Hello World


Il contenuto del Makefile è abbastanza semplice da capire, man mano che aggiungiamo un file sorgente o un file header basterà aggiungerlo alla lista nel Makefile. Possiamo apportare tutte le modifiche che vogliamo nel Makefile e basterà invocare il comando make per compilare ed ottenere il file eseguibile.
Oltre a questo make si occupa di verificare se dall'ultima compilazione è cambiato qualcosa nei file sorgente, se nulla è cambiato ci verrà notificato.
Copiate ed incollate il testo in un file e salvatelo con il nome Makefile nella stessa directory dei file sorgente. Ora provate ad eseguire il comando
$ make

Decisamente più comodo, non è vero?



Passiamo ad un altro argomento: valgrind.
La scorsa volta avevamo installato valgrind in quanto ottimo strumento di debugging, in particolare per gli errori nella gestione delle allocazioni di memoria. La sintassi è semplice
$ valgrind ./[nome eseguibile]

L'eseguibile verrà avviato all'interno dell'ambiente di debugging di valgrind, il quale analizzerà tutte le allocazioni di memoria e le relative de-allocazioni delle stesse. Al termine del programma verrà stampato sul terminale un resoconto completo con un elenco degli eventuali errori rilevati.

Proviamolo con il nostro SDL Hello World
$ valgrind ./sdl_helloworld

L'esecuzione risulterà più lenta e alla fine avremo sul terminale un resoconto dettagliato.
Senza entrare troppo nei particolari, quello che ci interessa più di tutto il resto è l'ultima riga:
ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 2)

Nella sezione LEAK SUMMARY potete trovare altri dettagli sulle allocazioni di memoria.
E' ovvio che non è solo il vostro codice che viene analizzato, ma anche quello delle librerie utilizzate, quindi alcuni memory leaks possono essere causati da quest'ultime.

Bene, torniamo all'argomento principale di questo tutorial, SDL 2.
Nello scorso esempio abbiamo utilizzato la funzione SDL_loadBMP(), che carica un'immagine di tipo BMP (Windows bitmap) in un oggetto SDL_Surface.
Per quanto questa funzione sia molto comoda e semplice da utilizzare, il formato BMP è piuttosto limitato e scarsamente utilizzato al giorno d'oggi.
Nella libreria principale di SDL 2 non ci sono altre funzioni per caricare immagini di tipo diverse, quali ad esempio PNG o JPG, ma fortunatamente c'è un'altra libreria dedicata a questo scopo: SDL_image.

Prima cosa da fare è installare sul nostro sistema questa libreria.
$ su
(verrà richiesta la password di root)
# apt install libsdl2-image-dev



Ora che abbiamo installato SDL_image possiamo modificare il programma per aprire un'immagine di tipo PNG.

Aggiungiamo l'include con il file header di questa libreria in helloengine.h
#include <SDL2/SDL_image.h>

Come la libreria SDL 2 anche questa va inizializzata, quindi nella funzione init() della classe HelloEngine (helloengine.cc) aggiungiamo queste righe di codice per inizializzare SDL_image per il caricamento di immagini PNG, subito sotto l'inizializzazione di SDL 2.

// inizializzazione SDL_image per i file di tipo PNG
if ((IMG_Init(IMG_INIT_PNG) & IMG_INIT_PNG) != IMG_INIT_PNG)
{
    on_SDL_error(std::cout, "IMG_Init");
    return false;
}

Ora andiamo a modificare la parte di codice che carica l'immagine, è sempre nella funzione init() poco più in basso. Utilizzeremo la funzione IMG_LoadTexture() che ci restituisce direttamente un puntatore ad un oggetto di tipo SDL_Texture, quindi non avremo bisogno di crearla passando per un SDL_Surface.

// carica l'immagine in texture
std::string name = "helloworld.png";
if ((texture = IMG_LoadTexture(renderer, name.c_str())) == nullptr)
    on_SDL_error(std::cout, "IMG_LoadTexture");

Potete convertire l'immagine BMP in una di tipo PNG utilizzando Gimp e salvatela con il nome helloworld.png.

Prima di compilare ricordatevi che stiamo utilizzando un'altra libreria, quindi dovremo modificare il nostro Makefile aggiungendo -lSDL2_image alla lista delle librerie da linkare, subito dopo -lSDL2.

Terminate le modifiche questo è quello che dovreste ottenere
Compilate con
$ make

Ed ora avviate il programma
$ -/sdl_helloworld

Se non avete fatto errori il programma funzionerà come prima.
Bene, in questa seconda parte del tutorial dedicato ad SDL 2 abbiamo preso maggior confidenza con gli strumenti di sviluppo e debugging, inoltre abbiamo visto come usare la libreria SDL_image.
Nel prossimo tutorial faremo ulteriori modifiche e vedremo come funziona la gestione degli eventi.

martedì 20 dicembre 2016

Iniziare a programmare con SDL 2 su Linux


SDL (Simple DirectMedia Layer) è una libreria di sviluppo multi-piattaforma, scritta in linguaggio C, progettata per controllare facilmente video, grafica, audio, tastiera, mouse, joystick, ecc...
Queste capacità la rendono ideale per lo sviluppo di videogiochi, applicazioni multimediali ed emulatori.
Un grande vantaggio è il fatto di essere multi-piattaforma, questo infatti semplifica il porting sulle diverse piattaforme supportate (Linux, OS X, Windows, iOS e Android).
SDL 2.0 è rilasciata con licenza Zlib, che è una licenza per software libero ed è compatibile con la licenza GPL.

Vediamo subito come preparare il nostro sistema con tutti gli strumenti necessari per iniziare a programmare.
In questo tutorial utilizzerò Debian GNU/Linux 8.6 con il desktop manager di default GNOME.
Probabilmente già saprete che Debian è una distribuzione GNU/Linux universale ed è la base di molte altre distribuzioni derivate, tra le quali Ubuntu. Utilizzare Debian in questo tutorial mi permette di abbracciare una grossa fetta di utenti Linux.

La prima cosa di cui abbiamo bisogno sono gli strumenti di sviluppo fondamentali, quali il compilatore, il linker ed un debugger.
Il pacchetto build-essential ci fornirà tutta la suite di programmi utili allo sviluppo.

$ su
vi verrà chiesta la password di root.
Controlliamo se ci sono aggiornamenti del sistema disponibili con
# apt update
Se trovati procediamo con l'aggiornamento con
# apt upgrade

Quindi installiamo build-essential
# apt install build-essential


Analizzando la lista dei pacchetti installati, forse avrete notato che gdb (il debugger GNU) è nella lista dei pacchetti consigliati, ma non è stato installato. Possiamo installarlo manualmente con
# apt install gdb
Oppure verrà installato automaticamente quando andremo ad installare Valgrind.
Valgrind è un ottimo software di debug e profiling che, tra le altre cose, permette di scovare gli errori nella gestione della memoria, come ad esempio i memory leaks, ossia le allocazioni di memoria che non vengono liberate al termine del loro utilizzo.
# apt install valgrind


Ora che abbiamo gli strumenti fondamentali per lo sviluppo, possiamo installare la libreria SDL 2.0.

# apt install libsdl2-dev


Il pacchetto libsdl2-dev contiene la libreria SDL 2.0 e tutti i componenti fondamentali per sviluppare applicazioni con SDL, ma se provate a cercare i pacchetti libsdl2 disponibili troverete altri componenti che ne espandono le funzionalità.
# apt search libsdl2


Analizzeremo ed installeremo gli altri pacchetti nel prossimo tutorial, quando ci serviranno, per il momento iniziamo a fare un piccolo test di compilazione per verificare che tutte le operazioni di preparazione siano andate a buon fine.

Per questo tutorial utilizzerò gedit, l'editor di testo del desktop GNOME, semplice e leggero, sicuramente adatto per scrivere/modificare file di codice sorgente di piccole dimensioni.
Nonostante la sua estrema semplicità, con qualche piccolo accorgimento possiamo renderlo un discreto strumento di sviluppo.
Dopo aver lanciato gedit, clicchiamo sul menù dell'applicazione sulla barra dello schermo in alto accanto ad Attività, e selezioniamo la voce Preferenze. Comparirà una finestra con diverse opzioni divise per categorie, clicchiamo su Editor e modifichiamo l'ampiezza di tabulazione da 8 a 4. Personalmente trovo che 8 spazi siano decisamente troppi, ma siete liberi di impostare il numero di spazi che più vi aggrada.

Preferenze di gedit
Ora cliccate su Plugin e scorrete la lista in basso fino a trovare e spuntare l'opzione Terminale integrato. Questo ci permetterà di avere un Terminale nella parte bassa della finestra di gedit, evitando di dover passare da una finestra ad un'altra quando dobbiamo compilare o effettuare operazioni di debugging.


Adesso clicchiamo sull'icona menù, posta sulla finestra di gedit accanto al tasto x di chiusura, selezioniamo Vista e spuntiamo le voci Riquadro laterale e Riquadro inferiore.



Queste faranno visualizzare un riquadro laterale con la lista dei file aperti ed un riquadro inferiore con il Terminale integrato.
Per finire, nella barra di stato di gedit, cliccate su Testo semplice per far comparire un menù e selezionate C++ per usufruire della colorazione automatica del testo per la sintassi del linguaggio di programmazione che andremo ad utilizzare nel tutorial.


Al termine di queste personalizzazioni, gedit ha un aspetto decisamente più orientato alla programmazione e meno minimalista.

Facciamo un test veloce per verificare che tutto funzioni regolarmente, scriveremo il classico Hello World e proveremo a compilarlo.

E' indispensabile avere una conoscenza minima del linguaggio C++, altrimenti vi consiglio di andare a consultare un manuale o un tutorial specifico.
Salvate il file in Documenti con il nome helloworld.cc, quindi dal Terminale integrato di gedit, andate in Documenti e provate a compilare il vostro programma.

$ g++ helloworld.cc -o helloworld

Se non avete fatto errori la compilazione andrà a buon fine e potrete eseguire helloworld

$ ./helloworld
Hello World!

A questo punto facciamo un altro test, un nuovo Hello World, ma questa volta utilizzando SDL 2.
Andremo a creare una classe chiamata HelloEngine che sarà il motore della nostra applicazione, mentre nel file principale, chiamato sdl_helloworld.cc ci sarà la funzione main() che si occuperà di creare un'istanza di HelloEngine ed avviarne l'esecuzione.
E' una struttura simile a quello che si utilizza per lo sviluppo di un videogioco, in questo caso è molto semplificata in quanto non ha un loop e non gestisce alcun evento. Questo programma si limiterà ad aprire una finestra e visualizzare il messaggio Hello World, dopo 2 secondi d'attesa chiude la finestra e termina.

Questi sono i tre file del nostro SDL Hello World.

Iniziamo ad esaminare il file header della classe HelloEngine, all'inizio del file andiamo ad includere iostream e SDL2/SDL.h.
Il secondo è ovviamente indispensabile per utilizzare la libreria SDL2, mentre il primo è necessario quando andiamo a stampare gli eventuali messaggi d'errore tramite std::ostream.

Le funzioni membro sono solo 4:
- init() si occupa di inizializzare HelloEngine;
- start() avvia l'esecuzione;
- render() disegna l'immagine caricata nella finestra;
- on_SDL_error() stampa il messaggio d'errore sullo std::ostream indicato.

Per il resto il file header è piuttosto semplice, andiamo a vedere come queste 4 funzioni sono implementate in helloengine.cc.

Init() è la funzione che inizializza l'ambiente SDL invocando SDL_Init(), prima di poter utilizzare qualsiasi funzione della libreria SDL2 dobbiamo inizializzarla con questa funzione. Successivamente viene creata una finestra con SDL_CreateWindow(), quindi viene creata un'istanza di SDL_Renderer che ci servirà per tutte le operazioni grafiche.
Per finire viene caricata un'immagine BMP ottenendo un oggetto SDL_Surface con il quale viene creato un oggetto SDL_Texture.
Dopo aver ottenuto la nostra texture, viene distrutto l'oggetto SDL_Surface con la funzione SDL_FreeSurface() liberando la memoria allocata.

render() è incaricata di disegnare sulla finestra.
SDL_RenderClear() cancella il contenuto di renderer, SDL_RenderCopy() disegna la texture ottenuta dal caricamento dell'immagine su renderer, infine con SDL_RenderPresent() viene visualizzato il contenuto di renderer sulla finestra.

Start() avvia l'esecuzione vera e proprio di HelloEngine, inizialmente invoca init() per effettuare tutte le inizializzazioni, quindi esegue la funzione render() per disegnare sulla finestra. SDL_Delay() attende per il numero di millesecondi indicato, nel nostro caso attende 2 secondi e quindi esce con valore 0 per indicare che non ci sono stati errori.

on_SDL_error() stampa un messaggio d'errore sullo std::ostream indicato, di fatto è sempre std::cout.

Infine è bene soffermarsi sul distruttore della classe HelloEngine, che si occupa di de-allocare tutta la memoria utilizzata dal programma.
SDL2 ha una funzione specifica per ogni tipo di oggetto da de-allocare, non possiamo utilizzare il semplice delete. Abbiamo visto in init() la funzione SDL_FreeSurface() per distruggere l'SDL_Surface, qui utilizziamo SDL_DestroyTexture per l'SDL_Texture, SDL_DestroyRenderer per l'SDL_Renderer e SDL_Quit per chiudere l'intero ambiente SDL.

Il file sdl_helloworld.cc contiene la funzione main() del programma, il funzionamento è estremamente semplice, crea un'istanza di HelloEngine e ne invoca l'esecuzione con start(). Al termine dell'esecuzione distrugge l'istanza con il delete ed esce con lo stesso codice d'uscita dell'istanza.


Andiamo a compilare SDL Hello World con

$ g++ -std=c++11 helloengine.h helloengine.cc sdl_helloworld.cc -o sdl_helloworld -lSDL2


Prima di eseguire ricordatevi di mettere l'immagine helloworld.bmp nella stessa directory dell'eseguibile, altrimenti verrà visualizzata una finestra completamente nera.


Immagine BMP utilizzata per questo test


L'immagine verrà salvata come JPG, potete esportarla in formato BMP utilizzando Gimp oppure ne potete creare una voi. Ricordatevi che per poter essere caricata correttamente da SDL_LoadBMP() l'immagine deve avere un unico livello.
 
$ ./sdl_helloworld


SDL Hello World in esecuzione

In questo tutorial abbiamo installato gli strumenti di sviluppo e la libreria SDL 2 sul nostro sistema ed abbiamo visto un primo esempio di applicazione sviluppata con questa libreria.
Nel prossimo tutorial vedremo come caricare immagini di altri formati, gestire eventi come la pressione di un tasto o il click del mouse ed altro ancora.

venerdì 2 dicembre 2011

Programmare con GTK+ in linguaggio C++: creare la prima applicazione!

Questo tutorial vi guiderà alla creazione di un programma con interfaccia grafica utilizzando il linguaggio C++ e la libreria Gtkmm, ma a differenza di molti altri tutorial sulla rete, utilizzeremo Glade e GtkBuilder per creare l'interfaccia.
Prima di iniziare, assicuratevi di aver installato Anjuta, Glade e la libreria libgtkmm, se non avete provveduto potete installarli tramite Ubuntu Software Center (se sei alle prime armi leggi questo ).
Faremo un programma semplice che illustrerà l'utilizzo di tre semplici elementi dell'interfaccia utente: un'etichetta per visualizzare del testo, un campo di inserimento per inserire una stringa di testo ed un pulsante. Alla pressione del pulsante, il testo inserito nel campo verrà visualizzato nell'etichetta.

La prima cosa da fare e' creare un nuovo progetto con Anjuta
  • Iniziamo con lanciare Anjuta e selezionare Nuovo – Progetto nel menu File o sulla barra degli strumenti.
  • Quando compare la finestra di selezione del tipo di progetto, selezionate C++ e quindi GTKmm, quindi cliccate su continua.
  • Nella schermata successiva date un nome al progetto, ad esempio tutorial, quindi se volete il vostro nome ed indirizzo email. Il numero di versione non e' importante, andiamo avanti.
  • Nel campo destinazione cliccate sul tasto apri e selezionate la posizione dove mettere il progetto. Vi consiglio di creare una cartella apposita.
  • Le altre opzioni le lasciamo con i valori di default, assicuriamoci soltanto che sia attiva la voce “Utilizzare GtkBuilder per l'interfaccia utente”, clicchiamo su continua e successivamente su applica.
Creazione di un progetto C++ GTKmm



Creare l'interfaccia utente con Glade

  • Adesso abbiamo un progetto, se proviamo ad eseguire il programma, dal menu Esegui – Esegui o dalla barra degli strumenti ( l'icona con gli ingranaggi ), si aprirà una finestra intitolata “Hello world!”. Chiudendo la finestra il programma terminerà.
  • Lanciate Glade, il disegnatore di interfacce, e aprite il file che definisce l'interfaccia del vostro programma. Se avete chiamato il progetto tutorial, lo troverete in tutorial/src/tutorial.ui
  • Il file contiene solo una finestra vuota. Selezionando la finestra nell'elenco in alto a destra, potrete vedere le proprietà nel riquadro in basso a destra. Il nome della finestra main_window e' quello di riferimento usato dal vostro codice per ottenere il puntatore alla finestra. Il titolo della finestra e' “Hello World!”, cambiamolo in “Tutorial 1”.
  • Il nostro programma necessita di tre elementi: un'etichetta, un campo inserimento ed un pulsante. Abbiamo quindi bisogno di un contenitore che contenga tre elementi. Nella colonna a sinistra di Glade potete vedere un pannello degli strumenti. Nella sezione Contenitori, selezionate il primo contenitore, quello denominato Casella, e' un widget di tipo Gtk::Box. Adesso cliccate all'interno della finestra del vostro programma. Vi verrà chiesto il numero di elementi, inserite 3 e cliccate su Crea.
  • Ora la nostra finestra può contenere tre elementi. Nel pannello degli strumenti, nella sezione Controllo e visualizzazione, selezionate Inserimento testo. La nostra finestra e' divisa in tre parti, cliccate sulla prima parte in alto, avete aggiunto il campo di inserimento testo. E' un widget di tipo Gtk::Entry.
  • Ora selezionate il widget Etichetta, posta nella sezione Controllo e visualizzazione del pannello degli strumenti. Quindi cliccate nel secondo spazio libero della vostra finestra. Avete così aggiunto l'etichetta, e' un widget di tipo Gtk::Label.
  • Per finire selezionate il widget Pulsante e cliccate nell'ultimo spazio libero della finestra. Il pulsante e' un widget di tipo Gtk::Button.
finestra vuota

aggiunto Gtk::Box di tre elementi

aggiunto Gtk::Entry

aggiunto Gtk::Label

aggiunto Gtk::Button

Adesso la nostra interfaccia e' completa, la sua composizione e' riassumibile con questo schema:

  • Gtk::Window
    • Gtk::Box
      • Gtk::Entry
      • Gtk::Label
      • Gtk::Button

Salvate l'interfaccia cliccando su Salva il progetto corrente nella barra degli strumenti in alto o dal menu File – Salva e tornate ad Anjuta.

Creare la classe di controllo dell'interfaccia Controller

Ora che avete salvato la nuova interfaccia, se provate ad eseguire il programma da Anjuta, vedrete comparire la finestra intitolata “Tutorial 1”, contenente i tre widget che avete aggiunto. Adesso dobbiamo creare una classe che si occuperà di gestire gli elementi dell'interfaccia grafica.

  • Create una nuova classe cliccando su Nuovo – Classe nella barra degli strumenti o dal menu File – Nuovo – Classe. Selezionate la sezione Classe C++ generica, chiamate la classe Controller, quindi cliccate su Crea. Si aprira un'altra finestra intitolata “Aggiungi sorgente”, nel riquadro sotto l'etichetta “Selezionare l'obbiettivo per i nuovi file sorgente:”, aprite la cartella src cliccando sul triangolino a sinistra, quindi selezionate tutorial e cliccate su Aggiungi. Ora abbiamo una nuova classe Controller, iniziamo ad implementarla.





  • Nel nostro main.cc potete vedere che viene creato un'istanza della classe Gtk::Builder leggendo il file tutorial.ui della nostra interfaccia. Dobbiamo quindi implementare un costruttore pubblico della classe Controller che riceva come parametro un puntatore a Gtk::Builder. Aggiungiamo quindi:
    inline Controller( Glib::RefPtr<Gtk::Builder> _bldr );
  • Dimenticavo, la nostra classe Controller dovrà lavorare con gli elementi dell'interfaccia, quindi dobbiamo includere il file header di gtkmm.
    Aggiungiamo quindi
    #include <gtkmm.h>
  • Controller necessita di tre variabili per contenere i puntatori degli elementi dell'interfaccia. Aggiungiamo quindi le seguenti variabili come private:
    Gtk::Entry *campoInserimento;
    Gtk::Label *campoEtichetta;
    Gtk::Button *pulsante;
  • Il compito del costruttore e' ottenere i puntatori dei tre elementi dell'interfaccia tramite l'istanza di Gtk::Builder e memorizzarli nelle tre variabili che abbiamo dichiarato come private. Aggiungiamo in Controller.h la definizione del costruttore:

    inline Controller::
    Controller ( Glib::RefPtr<Gtk::Builder> _bldr )
    {

    _bldr->get_widget ("entry1", campoInserimento);

    _bldr->get_widget ("label1", campoEtichetta);

    _bldr->get_widget ("button1", pulsante);
    }
    get_widget(nome, puntatore) e' un metodo di Gtk::Builder che richiama l'elemento con il nome posto nella stringa usata come primo parametro e mette il puntatore dentro alla variabile fornita come secondo parametro. entry1, label1 e button1 sono i nomi dei nostri widget, se tornate in Glade e selezionate gli elementi potrete verificarne i nomi. Ovviamente se modificate i nomi ricordatevi di modificare i nomi anche nel vostro codice sorgente.

Adesso il vostro Controller.h dovrebbe essere come questo:

#ifndef _CONTROLLER_H_
#define _CONTROLLER_H_

#include <gtkmm.h>

class Controller
{
      public:
            inline Controller( Glib::RefPtr<Gtk::Builder> _bldr );

      protected:

      private:
            Gtk::Entry *campoInserimento;
            Gtk::Label *campoEtichetta;
            Gtk::Button *pulsante;

};

inline Controller::
Controller ( Glib::RefPtr<Gtk::Builder> _bldr )
{
      _bldr->get_widget ("entry1", campoInserimento);
      _bldr->get_widget ("label1", campoEtichetta);
      _bldr->get_widget ("button1", pulsante);
}

#endif // _CONTROLLER_H_

Implementare il metodo aggiornaEtichetta

Il metodo aggiornaEtichetta ha il compito di prelevare la stringa inserita nel campo di inserimento e metterla nell'etichetta, vediamo come.

  • Dichiariamo il metodo aggiornaEtichetta come protetto nella nostra classe Controller, aggiungiamo quindi la dichiarazione:
    void aggiornaEtichetta ( void );
    Questo metodo non prende alcun parametro e non rilascia alcun valore alla sua uscita.
  • Adesso implementiamo la definizione di aggiornaEtichetta nel file controller.cc

    void Controller::
    aggiornaEtichetta ( void )
    {
          Glib::ustring stringa = campoInserimento->get_text ();
          campoEtichetta->set_text ( stringa );
    }

    Il funzionamento e' banale, prende la stringa contenuta in campoInserimento con il metodo get_text() e la mette in una variabile di tipo Glib::ustring*, quindi passa la stringa al campoEtichetta con il metodo set_text().

Collegare il pulsante al metodo aggiornaEtichetta

Adesso dobbiamo fare in modo che quando si clicca sul pulsante venga chiamato il metodo aggiornaEtichetta.

  • Andiamo a modificare il costruttore della classe Controller per aggiungere il collegamento.

    pulsante->signal_clicked ().connect (sigc::mem_fun (this, &Controller::aggiornaEtichetta) );

    Questa istruzione collega il segnale signal_clicked() del pulsante al metodo aggiornaEtichetta della nostra classe Controller.
  • La nostra classe Controller e' completa, ora modifichiamo il file main.cc per utilizzarla.
    Prima cosa da fare e' includere il file header controller.h

    #include “controller.h”
  • Quindi inseriamo la creazione di un'istanza di Controller invocando il costruttore che abbiamo implementato.

    Controller *controllo = new Controller ( builder );

    Dobbiamo passare al costruttore il puntatore dell'istanza di Gtk::Builder, quindi va messo dopo la creazione della stessa.
    Prima della fine di main() bisogna deallocare l'istanza di Controller

    delete controllo;

    main.cc sarà più o meno così

    #include <gtkmm.h>
    #include <iostream>
    #include "config.h"
    #include "controller.h"
    #ifdef ENABLE_NLS
    # include <libintl.h>
    #endif
    /* For testing propose use the local (not installed) ui file */
    /* #define UI_FILE PACKAGE_DATA_DIR"/tutorial_1/ui/tutorial_1.ui" */
    #define UI_FILE "src/tutorial_1.ui"
    int
    main (int argc, char *argv[])
    {
          Gtk::Main kit(argc, argv);
          //Load the Glade file and instiate its widgets:
          Glib::RefPtr<Gtk::Builder> builder;
          try
          {
                builder = Gtk::Builder::create_from_file(UI_FILE);
          }
          catch (const Glib::FileError & ex)
          {
                std::cerr << ex.what() << std::endl;
                return 1;
          }
          Gtk::Window* main_win = 0;
          builder->get_widget("main_window", main_win);
          Controller *controllo = new Controller ( builder );
          if (main_win)
          {
                kit.run(*main_win);
          }
          delete controllo;
          return 0;
    }

Compilazione e test del programma Tutorial

Il programma e' completo, potete compilare cliccando sull'icona di compilazione nella barra degli strumenti o sul menu Genera – Compila. Lanciate il programma e provate a scrivere qualcosa nel campo di inserimento, quindi cliccherete sul pulsante, vedrete l'etichetta visualizzare la stringa che avete inserito.

Il programma Tutorial 1 e' completo


Questo piccolo programma e' banale, ma penso che dia un'idea di come utilizzare Gtk::Builder.