Capítulo II: Programa Gráfico en C++.


Añadiendo componentes

Nuestro primer programa gráfico era "muy" elemental, complíquemoslo un poquito añadiéndolo una etiqueta (lo habitual en otros tutoriales es añadir un botón pero seamos originales, demostrando así, que no copíamos otros ejemplos- que tan poco importaría):
Práctica II-2: En Anjuta, crea un proyecto nuevo, selecciona programa proyecto Gtkmm 2.0 (por defecto el lenguaje de programación es  C++), como nombre practica_II_2  (o el que se te antoje).

Recuerda que dará error al generar el proyecto. Edita el archivo configure en la carpeta correspondiente /home/[usuario]/Projects/practica_II_2 y reemplaza las alusiones a gtkmm-2.0 por gtkmm-2.4 (que es la librería que nosotros hemos instalado).

Si al generar el proyecto no te aparece el archivo main.cc, sino otros distintos (nombre_programa.cc, windows1.cc, windows1.hh, windows1_glade.cc,  windows1_glade.hh ) tienes instalado el programa glademm que genera dichos archivos.  
Para seguir las siguientes instrucciones deberías desinstalarlo (provisionalmente).

Modificamos el archivo de main.cc para que quede tal que así:
/* Created by Anjuta version 1.2.4a */
/*    This file will not be overwritten */


#include <gtkmm.h>
#include <glib.h>

int
main(int argc, char *argv[])
{  
    GString * mensaje;
    mensaje = g_string_new( "Hola ");
    if (argc>1)
    {
        g_string_append(mensaje, argv[1]);
    }else{
        g_string_append (mensaje, "DESCONOCIDO");
    }
   
   
    Gtk::Main programa(argc, argv);

    Gtk::Window miventanica;

    Gtk::Label etiqueta(mensaje->str);
    miventanica.add(etiqueta);
    etiqueta.show();   

    miventanica.set_title("maestrodenada.com");


    Gtk::Main::run(miventanica);// Echar a correr nuestra ventana
   
    return 0;
}

Para ejecutarlo, vamos al menú [Construir->Configurar parámetros del programa...], en la caja de parámetros del comando introducimos lolo y pulsamos el botón ejecutar y...


... aparece está "M", si bien es cierto que si cogemos el ratón y lo estiramos llegamos a ver algo más


Explicación:

Por razones obvias, solo explico los comandos o instrucciones que son nuevos:

Gtk::Label etiqueta(mensaje->str);


Es la declaración e inicialización de un objeto Label (Gtk::Label).

miventanica.add(etiqueta);

El objeto Label, había sido declarado e inicializado, pero no estaba asociado a nuestra ventana. Esta segunda instrucción (comentada) lo que hace es añadir (add en inglés = añadir en español) el objeto Label [etiqueta] al objeto Window [miventanica]

etiqueta.show();

Los componentes añadidos en una ventana, por defecto, parecen no estar visibles. Así que para que sean visibles hay que utilizar esta función.


La tentación vive arriba... añadiendo más componentes: los contenedores

Parece que hubiésemos aprendido algo, ¿serías capaz de añadir un botón a nuestra aplicación? un botón es un objeto Gtk::Button, se declaran e inicializan tal que así:
 Gtk::Button nombre ("Púlsame");
 
Quizás tengas la tentación de hacer algo como esto:
/* Created by Anjuta version 1.2.4a */
/*    This file will not be overwritten */

#include <gtkmm.h>

#include <glib.h>

int main(int argc, char *argv[])
{  
    GString * mensaje;
    mensaje = g_string_new( "Hola ");
    if (argc>1)
    {
        g_string_append(mensaje, argv[1]);
    }else{
        g_string_append (mensaje, "DESCONOCIDO");
    }
   
   
    Gtk::Main programa(argc, argv); 

    Gtk::Window miventanica;
    Gtk::Label etiqueta(mensaje->str);
    miventanica.add(etiqueta);
    etiqueta.show();   
    miventanica.set_title("maestrodenada.com");

    Gtk::Button contador("pulsame");
    miventanica.add(contador);
    contador.show();

    Gtk::Main::run(miventanica);
   
    return 0;
}


El programa compila a la perfección, todas las instrucciones son correctas, pero... a la hora de ejecutarlo existe un pequeño problema que las librerías de Gtkmm nos advierten: La función add solo nos permite añadir un widget a la ventana principal, ...pero yo quiero dos o más...

Esto es así, porque Gtk::Window está desarrollada como un contenedor simple, sólo admite un widget (heredan de Gtk::Bin la función add() y remove(), para añadir y quitar el widget.

Pero en Gtkmm existen contenedores que permiten añadir varios widget o controles, por ejemplo Gtk::VBox, Gtk::HBox .  Para añadir controles en estos contenedores se utilizan las funciones pack_start().

Esto es, para realizar algo como esto:

vamos a añadir a Gtk::Window un widget que permita añadir a su vez varios widgets, será el Gtk::VBox .

En este VBox (caja vertical) vamos a añadir tres elementos- con pack_start-, un widgets etiqueta (Gtk::Label), una línea separadora (Gtk::HSeparator) y un botón (Gtk::Button).

/* Created by Anjuta version 1.2.4a */
/*    This file will not be overwritten */


#include <gtkmm.h>



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

    // declarando todo lo que hace falta
    Gtk::Window miventanica;
    Gtk::VBox principal;
    Gtk::HSeparator linea;
    Gtk::Label etiqueta("Pulsa abajo");
    Gtk::Button contador("¡AQUÍ!");

    // añadimos el VBox al Window
    miventanica.add(principal);
   
    // añadiendo nuestros elementos al VBox
    principal.pack_start(etiqueta);
    principal.pack_start(linea);
    principal.pack_start(contador);
   
    // haciéndolo todo visible
    principal.show();
    etiqueta.show();
     contador.show();   
    linea.show();
   
    miventanica.set_title("maestrodenada.com");
    miventanica.resize(260,110);
   

    Gtk::Main::run(miventanica);
   
    return 0;
}
No sé muy bien las razones de diseño, pero lo cierto es que en los ejemplos que he ido encontrando por ahí [incluida la página oficial de gtkmm], lo habitual es que el primer contenedor VBox, contenga a su vez otros contenedores los cuales almacenan los controles.
En nuestro caso, tendríamos tres VBox, uno principal (que contiene a los otros dos y a la línea de separación), un VBox superior que contendría nuestra etiqueta y un VBox inferior que contendría el botón. Algo así:
/* Created by Anjuta version 1.2.4a */
/*    This file will not be overwritten */


#include <gtkmm.h>

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

    Gtk::Window miventanica;
    Gtk::VBox principal, cajasup, cajainf;
    Gtk::HSeparator linea;
   
    miventanica.add(principal);
    principal.show();
    principal.pack_start(cajasup);
    cajasup.show();
    principal.pack_start(linea);
    linea.show();
    principal.pack_start(cajainf);
    cajainf.show();
    Gtk::Label etiqueta("Pulsa abajo");
    cajasup.pack_start(etiqueta);
    etiqueta.show();
     Gtk::Button contador("¡AQUÍ!");
    cajainf.pack_start(contador);
    contador.show();   
    miventanica.set_title("maestrodenada.com");
    miventanica.resize(260,110);
   

    Gtk::Main::run(miventanica);
   
    return 0;
}
Interactuando...manejo de señales
Inicio