GTK++ con CLASES
Compilación separada
Lo
habitual, aunque no es necesario, es que la clase se escriba en
archivos distintos al archivo principal (main.cc). Y decimos archivos,
en plural, porque en C++ existen dos tipos de archivo: los .h y los .cc
Los .h son archivos de cabecera e incluyen las declaraciones de funciones y variables.
Los .cc son los archivos de código e incluyen todas las definiciones de las funciones, el código.
Vamos a descomponer nuestro programa en varios archivos, empecemos con main.cc, que se quedará tal que así:
/* *************************
*
MAESTRODENADA.COM *
*
presenta
*
*
el
*
* programa con
clase *
*
de
Gtk
*
***************************/
#include <gtkmm.h>
#include "ventana.h"
int main(int argc, char *argv[])
{
Gtk::Main programa(argc, argv);
ventana miventanica;
Gtk::Main::run(miventanica);
return 0;
}Observa que como en main(), solo se utilizan los tipos
Gtk::Main, y
ventana,
en los include solo aparecen las librerías gtkmm.h y ventana.h.
Como quiera que ventana.h es el archivo de cabecera donde vamos a
declarar la clase y no va a estar en los directorios del sistema sino
en el nuestro, no se utiliza <>, sino las comillas: #include
"ventana.h"
El archivo ventana.h, (pulsa archivo nuevo, copia y pega, y lo grabas en el mismo directorio):#ifndef _VENTANA_H
#define _VENTANA_H
#include <gtkmm.h>
// DECLARACIÓN DE LA CLASE
class ventana:public Gtk::Window
{
public:
ventana(); // declaración constructor
virtual ~ventana(); // declaración destructor
protected:
int veces; // ahora veces es miembro de ventana
// Relación de widgets
Gtk::VBox principal;
Gtk::HSeparator linea;
Gtk::Label etiqueta;
Gtk::Button contador;
// señales
virtual void pulsa_contador();
};
#endif
Aquí solo aludimos a objetos GTK, por lo que solo precisamos incluir la libreria gtkmm.
Ahora bien, se observan nuevas directivas del preprocesador:
- #ifndef
XXXXXXXXX
... #endif
Esta
directiva le dice al compilador que si no se encuentra definida la
macro XXXXXXXXX se proceda a la lectura e interpretación del
texto hasta #endif.
Esta directiva define durante la compilación la siguiente macro.
Con
esto, conseguimos que la declaración de la clase se lea una
única vez por el compilador. La primera vez que se accede al
archivo se define la macro, en futuras ocasiones ya se encuentra
definida la macro y no se lee el archivo. Si esto no fuera así,
y tuviésemos varios ficheros leyendo ventana.h, la clase
sería declarada en varias ocasiones, generando confusión
al compilador y, por tanto, error.
Por último, ventana.cc:#include "ventana.h"
#include <gtkmm.h>
#include <iostream>
#include <stdlib.h>
// DEFINICIÓN DE LOS MÉTODOS DE LA CLASE
// constructor de la clase
ventana::ventana():principal(),linea(),etiqueta("Pulsa
abajo"),contador("¡AQUÍ!")
{
veces=0;
add(principal);
principal.pack_start(etiqueta);
principal.pack_start(linea);
principal.pack_start(contador);
principal.show();
etiqueta.show();
linea.show();
contador.show();
contador.signal_clicked().connect(sigc::mem_fun(*this,&ventana::pulsa_contador)
);
set_title("maestrodenada.com");
resize(260,110);
}
// destructor
ventana::~ventana(){std::cout<<"Eso es todo
amigo"<<std::endl;}
// función para manipular la señal
void ventana::pulsa_contador(){
char h[30];
sprintf (h, "has pulsado %i veces el
botón", ++veces);
etiqueta.set_text(h);
}
En este código se utilizan las librerías
stdlib.h [sprintf()], iostream [std::cout], gtkmm [of ocurse] y
ventana.h, que contiene la declaración de la clase.
Vamos a proceder a construir el proyecto...ERROR no está definido ventana::ventana()Esto
es así, porque aunque estemos editando a la vez los distintos
archivos, no hemos realizado la inclusión de los mismos en el
proyecto, y las ordenes de compilación solo hacen referencia a
main.cc.
Solución

En el menú proyecto, pulsamos sobre [Añadir archivo fuente], apareciéndonos la ventana de la izquierda.
Buscamos nuestro archivo cc, pulsando sobre el botón [Seleccione un archivo para añadir].
Como objetivo seleccionamos el ejecutable. En mi caso, basico2. Y finalmente [añadir]
Tras esto la construcción del proyecto y la compilación no dan errores.