Sep 10, 2010

Usar una interfaz dual en aplicaciones basadas en Qt

Supongamos que necesitamos crear un programa, el cual debe funcionar tanto en una PC normal(computadora de escritorio, laptops, netbooks, etc.), como en dispositivos móviles(teléfonos celulares, smartphones, etc.). Claramente resulta imposible utilizar la misma interfaz para ambos sistemas, ya que la cantidad y la disposición de los elementos que podemos colocar en una aplicación para PC es muy diferente de la que podemos usar en un dispositivo móvil, principalmente debido a la limitación que ofrece el tamaño de la pantalla de los dispositivos móviles.
Lo que vamos a ver es como podemos adaptar con muy pocas lineas de código hacer que nuestro programa sea capaz de utilizar dos formularios(.ui) diferentes sin modificar demasiado los archivos referentes a la clase(.cpp y .h).


Para que se entienda mejor, lo que vamos a hacer es crear dos formularios(.ui), uno por cada plataforma, y conectarlos exactamente a la misma clase(.cpp y .h), lo que implica que ambas interfaces comparten las mismas propiedades y los mismos métodos, y los utilizan de acuerdo a su necesidad.
Veamoslo mejor en este gráfico:


Entonces, al momento de compilar el programa elegiremos una u otra interfaz de acuerdo a nuestras necesidades.
Creemos un nuevo proyecto en QtCreator y veamos como se aplica esta idea.
Vamos a "File"->"New File or Project".


Seleccionamos "Qt C++ Project"->"Qt Gui Application".


Le damos un nombre al proyecto.


Seleccionamos el target de nuestro proyecto.


Aquí es donde creamos la clase para nuestra interfaz. El archivo para el formulario lo dejamos tal y como esta, mas adelante lo modificaremos, según nuestras necesidades.


En este proyecto no agregamos control de versiones ya que se trata solo de una prueba.


Una vez creado el proyecto agregamos un nuevo formulario.


Seleccionamos "Qt"->"Qt Designer Form"


Seleccionamos exactamente el mismo tipo de widget que el que tenia la clase que habíamos creado al principio.


Le damos un nombre.


Nuevamente el control de versiones es innecesario.


Ahora le vamos a cambiar el nombre del archivo del primer widget por uno mas adecuado.



Y modificamos el nombre de ambos formularios para que coincidan.


Ahora agregaremos una nueva cabecera. Desde esta cabecera es desde donde controlaremos la interfaz a usar al momento de compilar nuestro programa.


Y aquí es donde aplicamos el truco.
Pero primero debemos entender de que manera hace Qt para integrar la interfaz(.ui) en nuestro programa. Tenemos dos formas.
La primera forma es cargando la interfaz en tiempo de ejecución, esto se hace a través del objeto QUiLoader, pasándolo como parámetro el archivo donde se encuentra nuestra interfaz.
La segunda forma es tomando el archivo .ui, el cual internamente se trata de un archivo XML, QtCreator traduce este archivo XML y lo convierte a su correspondiente representación en código fuente(.h y .cpp).
QtCreator usa la segunda forma, si revisamos dentro del archivo mainwindow.cpp veremos la linea #include "ui_mainwindow1.h", la cual apunta al primer widget que creamos, y por lo tanto cuando el programa se ejecute mostrará la primera interfaz, si la cambiamos por #include "ui_mainwindow2.h" apuntara al segundo widget, y por lo tanto cuando el programa se ejecute mostrará la segunda interfaz. Pero ambas tendrán acceso a la misma clase, sus atributos y sus métodos, simplificando así la tarea programación, el usuario notara el cambio visual pero el programa internamente será el mismo.
Para ello, lo que haremos sera crear una macro que represente la cabecera de ambos widgets y que se modifique de acuerdo a la plataforma de destino, y reemplazamos la cabecera original por la macro, así.


Y aquí podemos apreciar mejor la idea.


Ok, ya se que no pulí mucho la presentación de las imágenes :P, pero a los fines educativos es mucho mas que suficiente como para entender la idea.
Aquí pueden descargar el código fuente completo del ejemplo.

No comments:

Post a Comment