Glade3 e Gtk… un primo programmino in C++

5 09 2007

Questa vuole essere una piccola introduzione allo sviluppo in C++ utilizzando Glade3, per la creazione dell’interfaccia utente, e le librerie Gtk

Per questo programmino, ci faremo aiutare dagli autotools, quindi creiamo una directory, ad esempio “ex1″:
mkdir ex1
ed al suo interno creiamo un file configure.ac come il seguente:
AC_INIT(src/main.cc)
AM_INIT_AUTOMAKE(ex1,0.1)
AC_CONFIG_HEADER(config.h)
AC_PROG_CC
AC_PROG_CXX
AC_PROG_INSTALL
AC_PROG_LIBTOOL
PKG_CHECK_MODULES([GTKMM], [gtkmm-2.4 >= 2.8.0])
PKG_CHECK_MODULES([GLADEMM], [libglademm-2.4])
AC_SUBST(GTKMM_CFLAGS)
AC_SUBST(GTKMM_LIBS)
AC_SUBST(GLADEMM_CFLAGS)
AC_SUBST(GLADEMM_LIBS)
AC_OUTPUT(Makefile src/Makefile)

sempre in questa cartella, creiamo il file Makefile.am, al cui interno mettiamo:
SUBDIRS = src
così da avere il codice separato dagli altri files e quindi creiamola:
mkdir src
cd src

e dentro inseriamo il file Makefile.am
bin_PROGRAMS=ex1
ex1_SOURCES=main.cc wmain.h wmain.cc
EXTRA_DIST = wmain.glade
INCLUDES = $(GTKMM_CFLAGS) $(GLADEMM_CFLAGS)
LIBS = $(GTKMM_LIBS) $(GLADEMM_LIBS)

Siamo quindi pronti a scrivere il codice, iniziamo dal main.cc:

#include <iostream>
#include "wmain.h"

int main(int argc, char *argv[])
{
    Gtk::Main kit(argc, argv);

        Glib::RefPtr<Gnome::Glade::Xml> refXml;
        try    {
                refXml = Gnome::Glade::Xml::create("wmain.glade");
        }
        catch(const Gnome::Glade::XmlError& ex)        {
                std::cerr << ex.what() << std::endl;
                return 1;
        }

        wMain* W = 0;
        refXml->get_widget_derived("wMain", W);
        if(W)  {
                kit.run(*W);
        }

        delete W;

    return 0;
}


questo provvederà a caricare il file .glade (vediamo dopo come crearlo), estrarre il widget wMain, “associarlo” ad una nostra classe ed a lanciare l’applicazione
Vediamo come creare la nostra classe, iniziamo dall’header wmain.h:

#ifndef WMAIN_H
#define WMAIN_H

#include <gtkmm.h>
#include <gtkmm/button.h>
#include <libglademm.h>
#include <iostream>

using namespace std;

class wMain : public Gtk::Window {
public:
        wMain(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& refGlade);
        virtual ~wMain();
        virtual void btnEsci();
        virtual void btnOk();
private:
        Gtk::Entry *txtNome;
};

#endif


Quindi passiamo al wmain.cc:

#include "wmain.h"

wMain::wMain(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& refGlade) : Gtk::Window(cobject) {
        Gtk::Button *btn;

        /** btnEsci */
        refGlade->get_widget("btnEsci", btn);
        if (btn) {
                btn->signal_clicked().connect( sigc::mem_fun(*this, &wMain::btnEsci) );
        } else {
                cerr << "btnEsci non trovato!" << endl;
        }

        /** btnOk */
        refGlade->get_widget("btnOk", btn);
        if (btn) {
                btn->signal_clicked().connect( sigc::mem_fun(*this, &wMain::btnOk) );
        } else {
                cerr << "btnOk non trovato!" << endl;
        }

        refGlade->get_widget("txtNome", txtNome);

}

wMain::~wMain() {
}

void wMain::btnEsci() {
        cout << "Esci" << endl;
        Gtk::Main::instance()->quit();
}

void wMain::btnOk() {
        Glib::ustring txt;
        txt="Testo ["+txtNome->get_text()+"]";
        Gtk::MessageDialog dlg(*this, txt, false, Gtk::MESSAGE_INFO,
                               Gtk::BUTTONS_OK, true);
        dlg.run();
}


praticamente abbiamo definito la classe wMain derivata dalla Gtk::Window, nel costruttore abbiamo quindi “cercato” i due tasti “btnEsci” e “btnOk”, collegando l’evento “clicked” ai nostri metodi wMain::btnEsci e wMain::btnOk, e abbiamo memorizzato il puntatore alla GtkEntry txtNome.
Nel metodo wMain::btnOk, andiamo ad estrarre il valore inserito nella entry e visualizzarlo tramite un message box, mentre in wMain::btnEsci lanciamo il Gtk::Main::instance()->quit() che termina l’applicazione.
Ora possiamo creare l’interfaccia grafica usando Glade3, quindi da terminale e dentro la cartella src lanciamo:
glade-3
Quello che ci comparirà sarà:

dalla tavolozza (dock a sinistra), premiamo il tastino “Finestra”

sempre dalla tavolozza, selezioniamo il contenitore “Casella verticale” ed impostamo il numero di elementi a 2

per ogni elemento (il box creato) inseriamo una “Casella orizzontale” di 2 elementi

Nel box in alto a sinistra inseriamo una GtkLabel selezionando dalla tavolozza, nel riquadro “Controlli e visualizzazione” il tastino “Etichetta”
Nel box in alto a destra invece inseriamo una GtkEntry (tastino “Entrata testo” sempre in “Controlli e visualizzazione”)
Nei box sotto inseriamo due GtkButton (tastino “Pulsante”)

impostando nelle proprietà la tipologia come “Stock” (vedi barra evidenziata)

la prima con “Pulsante stock” in “Applica”, l’altra con “Chiudi”

Ora non resta che assegnare i nomi come nella seguente figura

Salviamo quindi il file nella cartella “src” col nome “wmain.glade” e, tornando nella cartella principale del progetto diamo i comandi:
touch NEWS README AUTHORS ChangeLog
touch stamp-h
aclocal
autoheader
libtoolize -f
automake -ac --foreign
autoconf

Se tutto è andato bene, diamo un
./configure
make

e per lanciare il nostro programmino
cd src
./ex1

Buon divertimento! ;)

Pacchetti da installare
Ci sono una serie di pacchetti che occorre avere prima di procedere con lo sviluppo:
sudo apt-get install build-essential automake1.9 pkg-config libglademm-2.4-dev libgtkmm-2.4-dev
potrebbero mancarne alcuni, in quel caso fatemi sapere cosa mi sono dimenticato ;)

Link utili
Sicuramente vi saranno di aiuto
http://www.gtkmm.org/docs/gtkmm-2.4/docs/tutorial/html/index.html
http://sourceware.org/autobook/autobook/autobook_toc.html


Azioni

Informazione

17 risposte a “Glade3 e Gtk… un primo programmino in C++”

14 09 2007
alexwizard (18:41:40) :

gran bel post davvero! davvero interessantissimo! complimenti!
io ho iniziato da poco a cimentarmi allo sviluppo con C++ & GTK+ & GLADE.
spero seguiranno altri tuoi post del genere… saresti di grande aiuto.
grazie.

14 09 2007
paper0k (21:28:02) :

Grazie! :D
Appena ho un po di tempo, scrivo qualcosa per GLADE+GNOME e sempre in C++ con gli autotools ;)

4 10 2007
ilpaso (10:58:48) :

bel post davvero. Mi servirebbe una mano per iniziare ad usare anjuta2.2.0 e glade3.
La mia principale difficoltà consiste nell’intercettare i signals provenienti dagli oggetti inseriti nella main window. Anjuta nel main di un programma di esempio (classico Hello world) ha una procedura che carica il file .xml generato in glade. Questo passaggio mi è chiaro ma non capisco come interagire con gli oggetti fatti in glade
grazie
ciao

4 10 2007
paper0k (13:32:30) :

Non ho mai usato Anjuta, comunque penso che questo link ti possa essere utile http://www.gtkmm.org/docs/gtkmm-2.4/docs/tutorial/html/apb.html#id2576849 ;)

5 10 2007
ilpaso (14:57:36) :

quasi risolto. Solo che mi da un errore che non riesco ancora a capire. Sono un po’ duro!
error: request for member ‘on_okbutton_clicked’ in ‘okbutton’, which is of non-class type ‘Gtk::Button*’

la riga incriminata è:
okbutton.signal_clicked().connect(sigc::ptr_fun(&on_okbutton_clicked));

il pezzo di codice dove creo il pulsante è:
…….
Gtk::Window* main_win = 0;
Gtk::Button* okbutton;
refXml->get_widget(”okbutton”, okbutton);
refXml->get_widget(”main_window”, main_win);

if (main_win)
{
if (okbutton) {
okbutton.signal_clicked().connect(sigc::ptr_fun(&on_okbutton_clicked));
} else {
//cerr << “btnEsci non trovato!” << endl;
}

kit.run(*main_win);
}
return 0;
………….

grazie per l’aiuto
ciao

5 10 2007
paper0k (17:26:25) :

Prova così
okbutton->signal_clicked().connect(sigc::ptr_fun(&on_okbutton_clicked));
;)

5 10 2007
ilpaso (17:34:03) :

era proprio quello. Ho ancora addosso gli influssi del java!

Grazie tante!

ci sentiamo
ciao

8 10 2007
giuseppe (19:18:41) :

aiuto!
mi scrive qst
configure.ac:2: error: m4_defn: undefined macro: _m4_divert_diversion
configure.ac:2: the top level
autom4te: /usr/bin/m4 failed with exit status: 1
aclocal: autom4te failed with exit status: 1

quando faccio aclocal
come posso fare per sistemare?

11 10 2007
paper0k (08:10:21) :

Forse hai una versione vecchia di autoconf… ho fatto una ricerca su Google ed ho trovato questo http://www.gnu.org/software/autoconf/manual/autoconf-2.57/html_node/autoconf_163.html vedi se fa al caso tuo ;)

22 10 2007
Marco0987 (20:27:52) :

Esiste anche una traduzione della guida ufficiale delle gtkmm, magari puo’ esservi utile.
http://itagtkmm.blogspot.com/

6 11 2007
Marco (11:06:48) :

Ciao,
ho un problema per far avviare il programma.
Mi compila tutto ma quando vado a dare il comando ./ex1 mi da questo errore:
(ex1:12767): libglademm-CRITICAL **: Glade::Xml::get_cwidget(): glade_xml_get_widget() failed for widget name=wMain

Mi puoi aiutare??!??

Grazie mille

Ps. complimenti per l’articolo

8 11 2007
paper0k (08:28:41) :

MMM… ma da Glade, la finestra principale (gtkWindow per intenderci) si chiama wMain? ;)

8 11 2007
Marco (08:55:58) :

Si si, si chiama wMain.
E ti dirò di più, per vedere se funzionasse tutto, ho fatto un copia e incolla del tuo codice, ma il risultato è sempre negativo. Sempre quell’errore.

8 11 2007
paper0k (21:46:58) :

Ho rieseguito nuovamente la guida, e la compilazione non ha dato problemi, l’unica cosa che penso possa essere, è il nome della finestra creata con Glade.
Dalla cartella src, lancia questo comando
grep GtkWin wmain.glade
devi avere id=”wMain” ;)

8 11 2007
Marco (23:12:49) :

Ok perfetto, risolto….
Grazie mille… ;-)

12 11 2007
teo_icKs (12:14:11) :

complimenti per il POST…
leggendolo, in pochissimo tempo sono stato operativo sviluppando per la prima volta in gtk+autoconf!!!!

Veramente tutto chiaro… semplice e completo.

Vista la tua abilià, potresti estendere il tutto in una miniguida….

P.S. La sto consigliando a tutti gli amici developer… anche quelli che già sviluppano in GTK+ perche comunque questa lettura fa bene a anche a loro :-)

29 12 2007
Torsten (02:04:22) :

Seems like a great first-step intro! Is there any chance you could translate this into German or English?

Lascia un commento

Puoi usare questi tag : <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>