Capítulo 3: ¡Qué aburrido! yo quiero interactuar

De doc.ubuntu-es
(Diferencias entre revisiones)
Saltar a: navegación, buscar
Línea 112: Línea 112:
 
   }
 
   }
  
Esa orden que hemos añadido lo que hace es crear un evento de cerrar, que es un evento que tiene la peculiaridad de tener una función ya asociada que se encarga de cerrarlo por nosotros, pero en breves momentos cambiaremos esda situación a nuestro favor.
+
Esa orden que hemos añadido lo que hace es crear un evento de cerrar, que es un evento que tiene la peculiaridad de tener una función ya asociada que se encarga de cerrarlo por nosotros, pero en breves momentos cambiaremos esa situación a nuestro favor.
  
 
Bueno, ya podemos hacer alguna prueba, compilamos, y ejecutamos. Vamos al menú "file", y seleccionamos "Exit Alt-F4". ¡Y se cierra! ¡Lo hemos logrado!
 
Bueno, ya podemos hacer alguna prueba, compilamos, y ejecutamos. Vamos al menú "file", y seleccionamos "Exit Alt-F4". ¡Y se cierra! ¡Lo hemos logrado!

Revisión de 13:52 21 jun 2008

Contenido

Introducción

En este capítulo comenzaremos a preparar la interfaz para que pueda interactuar con el usuario, e introduciremos (ya que son la misma cosa) los eventos. Este será un paso de gigante, ya que nos permitirá introducir un par de órdenes esenciales para todo código que vaya a entrar en bucles largos, para ello nos crearemos una barra de progreso que no hara más que rellenarse y vaciarse, y unos botones de start y stop.

Sería interesante introducir una pantalla para imprimir cosas, pero eso parece ya demasiado para este capítulo.

Así que nuestro plan de trabajo será tal que:

  • Plan de trabajo del capítulo 3:
    • Manejo de eventos (I):
      Crearemos nuestra primera tabla de eventos, y aprenderemos a manejar nuestros primeros eventos
      • Evento cerrar:
        • Evento cerrar del menú:
          Crearemos la respuesta al evento de cerrar a través del menú "file/exit..."
        • Evento cerrar de la barra de título:
          Crearemos la respuesta al evento de cerrar a través de la "X" de la barra de título.
    • Creación de una ProgressBar:
      Crearemos una Barra de progresos, y sus controles.
      • Barra de progreso:
        Haciendo uso de la documentación encontraremos cual es el objeto que buscamos, y lo implementaremos.
      • Controles de la barra:
        Crearemos una pequeña barra de herramientas para controlar a esta barra de progreso.
    • Manejo de eventos (II):
      Crearemos todo lo necesario para manejar la barra de control.
      • Evento de "Start":
        El que nos permitirá poner a funcionar la barra de progreso.
      • Evento de "Stop":
        El que nos permitirá parar la barra.
        • Cola de eventos:
          No impacientarse, veremos que es lo que ocurre...


Manejo de eventos

En la programación con interfaz gráfica, el manejo de eventos se vuelve la llave que abre todas las puertas, y es que nos permite hacer cosas que en un principio solo se podrían hacer acudiendo a los multiprocesos. La idea básicamente consistirá en lo siguiente, cada uno de los elementos de la interfaz gráfica, cada vez que se actúe sobre él, emitirá un evento, de una clase o de otra dependiendo la acción que se haya llevado (porque evidentemente no deberá comportarse igual cuando cambies su tamaño, que cuando lo cierres). Ese evento lo anclaremos mediante tablas de eventos, a un método (método = función) que ejecutará las acciones pertinentes (las que nosotros deseemos para esa actuación).


Evento cerrar

Para manejar nuestro primer evento, ya dejamos preparado un menú tal que "file/exit...". Este evento será muy interesante, ya que deberá compartir sus acciones con el evento de cerrar presionando sobre la "X" de la ventana. Eso nos enseñará dos cosas, como manejar eventos que necesiten ID, y como manejar los que no lo necesiten (que no tienen ninguna diferencia, pero que nos enseñará que en algunos casos, los eventos no necesitan ID), y lo que es más importante, nos enseñará a hacer las cosas bien (para no duplicar código).

Evento cerrar del menú

Bien, así que recuperamos nuestro trabajo donde lo dejamos, y acudimos presto a abrir "topframe.h". Las tablas de eventos hay que predeclararlas, y eso se hace en nuestra cabecera, simplemente añadiendo las siguientes líneas:

 class TopFrame : public wxFrame
 {
 public:
     TopFrame(wxString Title = _T("Welcome to wxWidgets"));
 private:
     // any class wishing to process wxWidgets events must use this macro
     DECLARE_EVENT_TABLE()
 };

Lo cierto es que nuestros eventos serán una cosa privada (private:), que sólo la clase en cuestión debe manejar, ya no sólo porque es intuitivamente lo lógico, sino porque nos puede ahorrar algunos problemillas.

Bueno, hemos declarado la tabla de eventos, ahora vamos a declarar un método para controlar el evento. Llamémoslo por ejemplo "OnQuit", y lo pondremos como privado, ya que será el que maneje el evento... No obstante, puede ocurrir que más tarde algún elemento pueda tener la necesidad de cerrar el programa, así que la gestión de cierre deberá ser algo publico, así que crearemos otro método llamado "Quit", que será realmente el que nos cierre la aplicación (todo esto tendrá un transfondo mucho más interesante, que entenderemos más adelante). También necesitamos saber que tipo de evento manejaremos, así que en nuestra API (a partir de ahora denominaremos así al wx.chm) buscamos wxMenu, y en el apartado "Event handling", nos da este evento: "wxCommandEvent", que será el que habremos de usar...

Así pues, nuestra cabecera deberá modificarse así:

 class TopFrame : public wxFrame
 {
 public:
     TopFrame(wxString Title = _T("Welcome to wxWidgets"));    
     void Quit();
 private:
     void OnQuit(wxCommandEvent& event);    
     // any class wishing to process wxWidgets events must use this macro
     DECLARE_EVENT_TABLE()

};

Donde efectivamente llevamos a cabo todas las operaciones que planteabamos...

El siguiente punto sin duda debería ser implementar todo esto, así que abrimos "topframe.cpp", y lo primero de todo añadimos la tabla de eventos:

 BEGIN_EVENT_TABLE(TopFrame, wxFrame)  
 END_EVENT_TABLE()
 
 TopFrame::TopFrame(wxString Title)
 : wxFrame(NULL, wxID_ANY, Title)
 {
   (...)

Ahora recuperamos nuestra documentación, justo en el lugar donde la dejamos, y nos encontramos que el macro en la tabla de eventos es "EVT_MENU", pero necesitamos saber como funciona, así que lo buscamos, y nos encontramos "wxCommandEvent", lo abrimos, y alli esta: "EVT_MENU(id, func) "

  • id: Ya lo conocemos, le pusimos wxID_EXIT.
  • func: La función a la queremos anclarlo la hemos declarado como OnQuit.

Así que la tabla de eventos quedará de la forma:

 BEGIN_EVENT_TABLE(TopFrame, wxFrame)
     EVT_MENU(wxID_EXIT,  TopFrame::OnQuit)
 END_EVENT_TABLE()

Ahora debemos implementar nuestros dos métodos, empezemos con el que maneja el evento (OnQuit), para ello, al final del archivo añadimos las siguientes líneas:

 void TopFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
 {
 }

Como no queremos sacrale más partido a este evento, pues con saber que se ha emitido la orden de cerrar nos es suficiente, ponemos como entrada "wxCommandEvent& WXUNUSED(event)". No actuaremos así por ejemplo cuando manejemos el ratón, pues necesitaremos información sobre donde estaba, o que botón apretó.

Bueno, este método lo único que hará será llamar a la función que realmente gestiona el cierre:

 void TopFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
 {
     Quit();
 }

Con esta argucia hemos arreglado un problema interesante, imaginemos que algún otro bjeto, o algún otro método quisieran cerrar la aplicación, de ser el gestor el anterior método, para llamarle sería necesario generar un evento, pues necesitariamos ese parámetro, pero ahora van a poder llamar a Quit(), y listos.

  • Esto se puede hacer de muchas maneras, una sería por ejemplo poner un evento por defecto, tal y como hicimos con el título de TopFrame, no obstante, esta manera me parece más legible.

Ahora toca, casi a la fuerza, implementar nuestro método "Quit", así que nuevamente al final de archivo añadimos:

 void TopFrame::Quit()
 {
 }

Y este método lo único que habrá de hacer bserá cerrar la aplicación:

 void TopFrame::Quit()
 {
     // true is to force the frame to close
     Close(true);
 }

Esa orden que hemos añadido lo que hace es crear un evento de cerrar, que es un evento que tiene la peculiaridad de tener una función ya asociada que se encarga de cerrarlo por nosotros, pero en breves momentos cambiaremos esa situación a nuestro favor.

Bueno, ya podemos hacer alguna prueba, compilamos, y ejecutamos. Vamos al menú "file", y seleccionamos "Exit Alt-F4". ¡Y se cierra! ¡Lo hemos logrado!

Ya sabemos crear menús, y anclarlos a eventos que apuntaran a los métodos que nos interese, pero vamos a seguir rizando el rizo...

Evento cerrar de la barra de título

 Contruyendo...
Capítulo 2.- ¡Esta vivo! ¡vivoooooo! ¡JAJAJA! Nuestra primera interfaz gráfica con CodeBlocks y wxWidgets Capítulo 4: Soy un artista... ¡No me coartes!
Herramientas personales