46172282 Tutorial de Qt

47
Tut orial de Qt - Capítulo 1 Resumen En nuestro primer programa mostraremos la típica frase "Hola Mundo!". Solo contiene lo indispensable para poner en marcha una aplicación Qt. La siguiente imagen es una captura de lo que vamos a hacer: Veamos el código completo de la aplicación: #include <QApplication> #include <QPushButton> int main ( int argc , char  * argv []) {  QApplication app ( argc , argv  );  QPushButton hello ( "Hola Mundo!"  ); hello.show ();  return app.exec ();  } Explicación #include <QApplication> Esta linea incluye la definición de la clase QApplication. Solo tiene que haber un objeto QApplication en cada aplicación con GUI que use Qt. QApplication maneja los diferentes recursos de la aplicación, como la fuente por defecto y el cursor. #include <QPushButton> Esta linea incluye la definición de la clase QPushButton. Para cada clase de la API de Qt existe un fichero de cabecera con el mismo nombre que contiene su definición. Un QPushButton es un botón de la GUI que el usuario puede pulsar y soltar. Maneja su propio look and feel , como cualquier otro QWidget. Un widget es un objeto de la interfaz de usuario que puede dibujar gráficos y procesar entradas por parte del usuario. E l programador puede cambiar tanto el aspecto general como otras muchas propiedades menores (como el color), asi como el contenido del widget. Un QPushButton puede mostrar un texto o un QIcon. int main ( int argc , char  * argv []) { 

Transcript of 46172282 Tutorial de Qt

8/4/2019 46172282 Tutorial de Qt

http://slidepdf.com/reader/full/46172282-tutorial-de-qt 1/47

Tutorial de Qt - Capítulo 1

Resumen

En nuestro primer programa mostraremos la típica frase "Hola Mundo!". Solo contiene lo indispensable para

poner en marcha una aplicación Qt. La siguiente imagen es una captura de lo que vamos a hacer:

Veamos el código completo de la aplicación:

#include <QApplication> 

#include <QPushButton> 

int main ( int argc , char  * argv [])

  QApplication app ( argc , argv  ); 

  QPushButton hello ( "Hola Mundo!"  ); 

hello.show (); 

  return app.exec (); 

 }

Explicación

#include <QApplication> 

Esta linea incluye la definición de la clase QApplication. Solo tiene que haber un objeto QApplication en

cada aplicación con GUI que use Qt. QApplication maneja los diferentes recursos de la aplicación, como la

fuente por defecto y el cursor.

#include <QPushButton> 

Esta linea incluye la definición de la clase QPushButton. Para cada clase de la API de Qt existe un fichero de

cabecera con el mismo nombre que contiene su definición.

Un QPushButton es un botón de la GUI que el usuario puede pulsar y soltar. Maneja su propio look and feel ,

como cualquier otro QWidget. Un widget es un objeto de la interfaz de usuario que puede dibujar gráficos y

procesar entradas por parte del usuario. El programador puede cambiar tanto el aspecto general como otras

muchas propiedades menores (como el color), asi como el contenido del widget. Un QPushButton puede

mostrar un texto o un QIcon.

int main ( int argc , char  * argv [])

8/4/2019 46172282 Tutorial de Qt

http://slidepdf.com/reader/full/46172282-tutorial-de-qt 2/47

La función main() es el punto de entrada del programa. Casi siempre que usemos Qt, main() solo necesitará

realizar algún tipo de inicialización antes de pasar el control a la biblioteca Qt, la cual le comunicará al

programa como actuar con el usuario a través de los eventos que genere.

El parámetro argc es el numero de argumentos pasados por la linea de ordenes, y argv es el array que

contiene dichos argumentos. Esto es una definición estándar de C++.

  QApplication app ( argc , argv  ); 

El objeto app es la instancia de QApplication de este programa. Pasamos argc y argv al constructor

de QApplication para que pueda procesar los argumentos de la linea de ordenes (como -display). Cada vez

que un argumento es reconocido por Qt, se elimina de argv y consecuentemente argc se decrementa. Para

mas detalles puedes ver QApplication ::arguments ().

El objeto QApplication debe crearse ante de usar cualquier elemento de la GUI de Qt.

  QPushButton hello ( "Hello world!"  ); 

Despues de QApplication viene el primer código relacionado con la interfaz, hemos creado un botón.

Establecemos que el botón muestre el texto "Hola Mundo!". Como no hemos especificado una ventana padre

(por ejemplo mediante el segundo argumento del constructor de QPushButton), el botón será una ventana en

si misma, con su propio marco de venta y su barra de titulo.

El tamaño del botón está determinado por su propio tamaño por defecto. Podríamos llamar

a QWidget ::move () para asignarle una posición determinada al widget, pero por ahora vamos a permitir que

el administrador de ventanas elija su posición.

  hello.show (); 

Un widget nunca es visible al usuario cuando lo creamos, debemos llamar a QWidget ::show () para hacerlo

visible.

  return app.exec (); 

 }

Aquí es donde main() pasa el control a Qt. QCoreApplication ::exec () terminará cuando se salga de la

aplicación (QCoreApplication es la clase base de QApplication. Implementa el núcleo deQApplication, la

funcionalidad no-GUI y puede usarse para desarrollar aplicaciones sin GUI).

8/4/2019 46172282 Tutorial de Qt

http://slidepdf.com/reader/full/46172282-tutorial-de-qt 3/47

En QCoreApplication ::exec (), Qt recibe y procesa los eventos del usuario y del sistema y los pasa a los

widgets apropiados.

Pasemos a compilar y ejecutar nuestro primer programa.

Compilar y ejecutar la aplicación.

Una vez creado el archivo .cpp en un directorio de trabajo, el siguiente paso es crear el makefile de Qt en

dicho directorio. Para crear un makefile de Qt vamos a usar qmake, la herramienta de trabajo que incorpora

Qt.

Ejecutamos las dos siguientes sentencias desde una terminal en nuestro directorio de trabajo para crear el

makefile.

qmake - project 

qmake 

La primer orden indica a qmake que cree un archivo de proyecto (.pro). La segunda le dice a qmake que use

el archivo .pro para crear el makefile.

Ahora podemos ejecutar make para compilar el programa, y si todo ha ido bien, ya podemos ejecutar nuestra

primera aplicación Qt!.

Ejercicios.

Intenta redimensionar la ventana. Pulsa el botón. Intenta ejecutar el programa con la opción -geometry (por

ejemplo -geometry 100x200+10+20).

ResumenEste ejemplo es una continuación de la ventana creada en el capitulo 1. Vamos a hacer quela aplicación se cierre correctamente cuando el usuario se lo diga.

También vamos a usar un tipo de letra mas atractivo de la que se muestra por defecto.

Veamos el código completo de la aplicación:#include <QApplication>#include <QFont>#include <QPushButton>

int main( int argc , char  *argv[]){   QApplication app( argc , argv );

8/4/2019 46172282 Tutorial de Qt

http://slidepdf.com/reader/full/46172282-tutorial-de-qt 4/47

  QPushButton quit ( "Quit"  );quit.resize( 75 , 30 );quit. setFont ( QFont ( "Times"  , 18 , QFont :: Bold  ));

  QObject ::connect (&quit  , SIGNAL( clicked ()), &app , SLOT ( quit ()));

quit. show();  return app.exec(); }

Explicación

#include <QFont>

Como vamos a usar QFont en nuestro programa, tenemos que incluir QFont.

  QPushButton quit ( "Quit"  );

Esta vez el botón mostrara el texto Quit, y eso será lo que el programa haga cuando lo pulsemos.

  quit.resize( 75 , 30 );

Hemos elegido otro tamaño para el botón ya que el texto es algo mas corto que "HolaMundo!". También podríamos haber usado QFontMetrics para establecer el tamañoadecuado, o permitir que QPushButton eligiera un tamaño razonable por defecto.

quit. setFont ( QFont ( "Times"  , 18 , QFont :: Bold  ));

Elegimos una nueva fuente para el botón: Times y negrita de 18 puntos. También es posiblecambiar la fuente por defecto de toda la aplicación mediante QApplication ::setFont ().

QObject ::connect (&quit  , SIGNAL( clicked ()), &app , SLOT ( quit ()));

QObject ::connect () es quizás la característica mas importante de Qt. Ten en cuenta queconnect() es una función estática de QObject, no confundirla con la función connect() de la biblioteca de sockets de Berkeley.

La llamada a connect( ) establece una conexión "en una sola dirección" entre dos objetos deQt (objetos que heredan de QObject, directa o indirectamente). Cada objeto de Qt puedetener signals (para mandar mensajes) y slots (para recibir mensajes). Todos los widgets sonobjetos de Qt ya que heredan de QWidget, que a su vez hereda de QObject.

En nuestro caso, la señal clicked( ) de quit se conecta al slot quit() de app, así cuando se pulsa el botón, se termina la ejecución de la aplicación.

La documentación de Signals and slots explica este mecanismo en profundidad.

Compilar y ejecutar la aplicación.Podemos compilar y ejecutar la aplicación de forma similar al capitulo 1. Si pulsamos el botón Quit, vemos como la aplicación termina su ejecución.

8/4/2019 46172282 Tutorial de Qt

http://slidepdf.com/reader/full/46172282-tutorial-de-qt 5/47

Ejercicios.Intenta redimensionar la ventana. Pulsa el botón para cerrar la aplicación.

¿Existe alguna otra señal de de QPushButton que puedas conectar al botón? (sugerencia:QPushButton hereda la mayor parte de su funcionalidad de QAbstractButton).

ResumenEn el tercer capítulo vamos a ver como crear widgets padres y widgets hijos de la formamas sencilla posible: creando un padre y un solo hijo.

#include <QApplication>#include <QFont>#include <QPushButton>#include <QWidget>

int main( int argc , char  *argv[]){   QApplication app( argc , argv );

  QWidget window;

window.resize( 200 , 120 );

  QPushButton quit ( "Quit"  , &window );quit. setFont ( QFont ( "Times"  , 18 , QFont :: Bold  ));quit. setGeometry( 10 , 40 , 180 , 40 );

  QObject ::connect (&quit  , SIGNAL( clicked ()), &app , SLOT ( quit ()));

window. show();  return app.exec(); }

Explicación

#include <QWidget>

Añadimos la cabecera de QWidget  para poder usarla.

  QWidget window;

Creamos simplemente un widget. La clase QWidget es la clase base de todos los objetos dela interfaz de usuario. Un widget es el átomo de la interfaz de usuario: captura el ratón, elteclado y otros eventos del administrador de ventanas, y dibuja una representación de si

8/4/2019 46172282 Tutorial de Qt

http://slidepdf.com/reader/full/46172282-tutorial-de-qt 6/47

mismo en la pantalla. Un widget queda recortado por su widget padre y por widgets queestan delante de él.

A un widget que no está relacionado con un widget padre, como el que hemos creado, se lellama ventana. Normalmente las ventanas tienen su propio marco de ventana y una entradaen la barra de tareas, proporcionado por el administrador de ventanas. Un widget sin widget

 padre siempre es una ventana independiente y su posición inicial en la pantalla estácontrolada por el administrador de ventanas.

  window.resize( 200 , 120 );

Establecemos el ancho de la ventana a 200 pixeles a la altura a 120 pixeles.

  QPushButton quit ( "Quit"  , &window );

Acabamos de crear un hijo :P. Este QPushButton se ha creado definiendo un widget padre(window). Un widget hijo siempre se muestra en el area del padre, y cuando se muestra esrecortado por los limites del padre. Por defecto se ancla a la esquina superior izquierda, enla posición (0, 0).

  quit. setGeometry( 10 , 40 , 180 , 40 );

La funcion QWidget ::setGeometry () tiene cuatro argumentos: los dos primeros son lascoordenadas x e y de la esquina superior izquierda del botón (relativas al widget padre), ylos dos últimos son la anchura y la altura del botón. El resultado es un botón que ocupadesde la posición (10, 40) hasta la posición (190, 80).

window. show();

Cuando mostramos un widget padre, este llamará a la función show() de cada uno de sushijos (excepto aquellos que se ocultaron explicitamente mediante QWidget:hide()).

Los lectores del tutorial que ya hayan estudiado la documentación de QObject recordaránque cuando se invoca al destructor de un QObject, si el QObject tiene hijos, el destructor invocado llamará automáticamente al destructor de cada hijo. Puede parece que el

destructor del botón quit se invocará dos veces al final de main(), una cuando su padre(window) sale de su ámbito y el destructor elimina el botón porque es hijo suyo, y otracuando el botón sale de su ámbito. No hay necesidad de preocuparse en este caso, ya que el código es correcto. De todasformas, existe un caso en el que el programador debe ser consciente del orden de ladestrucción de objetos en la pila (puedes ver la explicación del orden deconstrucción/destrucción de QObjects aqui).

Ejecutar la aplicación.A diferencia del capitulo 2 del tutorial, el botón ya no llena toda la ventana, sino que semantiene en la posición (10, 40) dentro de la ventana con un tamaño (180, 40), debido a la

llamada a QWidget::setGeometry().

Ejercicios.Intenta redimensionar la ventana, ¿Cómo cambia el botón? ¿Qué sucede con la altura del botón si se ejecuta el programa con un tipo de letra mas grande?¿Qué ocurre si intentashacer la ventana muy pequeña?

8/4/2019 46172282 Tutorial de Qt

http://slidepdf.com/reader/full/46172282-tutorial-de-qt 7/47

ResumenEn este capítulo vamos a ver como crear nuestro propio widget y como controlar el tamañomínimo y máximo de dicho widget.

#include <QApplication>#include <QFont>#include <QPushButton>#include <QWidget>

class MyWidget :  public QWidget {    public:

MyWidget ( QWidget  * parent = 0 ); };

MyWidget ::MyWidget ( QWidget  * parent  )  : QWidget (  parent  ){ 

setFixedSize( 200 , 120 );

  QPushButton *quit = new  QPushButton( tr ( "Quit"  ), this );quit -> setGeometry( 62 , 40 , 75 , 30 );quit -> setFont ( QFont ( "Times"  , 18 , QFont :: Bold  ));

  connect ( quit  , SIGNAL( clicked ()), qApp , SLOT ( quit ())); }

int main( int argc , char  *argv[]){   QApplication app( argc , argv );

MyWidget widget ;widget. show();

  return app.exec(); }

Explicación

class MyWidget :  public QWidget {    public:

8/4/2019 46172282 Tutorial de Qt

http://slidepdf.com/reader/full/46172282-tutorial-de-qt 8/47

MyWidget ( QWidget  * parent = 0 ); };

Lo primero que hacemos es crear una nueva clase. Como hereda de QWdiget, la nuevaclase podrá ser un widget (y quizá una ventana independiente) o un widget hijo (como elQPushButton del capítulo anterior ).

La clase solo tiene un miembro, el constructor (además de los miembros heredados deQWdiget). El constructor es un constructor estándar de widget de Qt; deberías incluir siempre un constructor similar cuando crees un widget.

El argumento del constructor es el widget padre. Para crear una ventana independiente conel widget debes especificar un puntero nulo como padre. Como puedes ver, el widget es por defecto una ventana independiente.

MyWidget ::MyWidget ( QWidget  * parent  )

La implementación del constructor empieza aquí. Como la mayoría de los widgets,simplemente pasa el argumento parent al constructor de QWdiget.

  : QWidget (  parent  )

{ setFixedSize( 200 , 120 );

Ya que el widget no sabe como manejar el redimensionado, fijamos su tamaño. En elsiguiente capítulo veremos como un widget puede responder al redimensionado por partedel usuario.

  QPushButton *quit = new  QPushButton( tr ( "Quit"  ), this );quit -> setGeometry( 62 , 40 , 75 , 30 );quit -> setFont ( QFont ( "Times"  , 18 , QFont :: Bold  ));

Creamos y establecemos un widget hijo de nuestro widget (el padre del nuevo widget esthis, es decir, la instancia de MyWidget ).

La función tr( ) marca la cadena "Quit" para que pueda ser traducida, haciendo posiblecambiarla en tiempo de ejecución según los archivos de traducción. Es un buen habito usar tr( ) en todas las cadenas visibles al usuario en el caso de que decidas traducir mas tarde tuaplicación a otros idiomas.

Ten en cuenta de que quit es una variable local del constructor. MyWdiget no hace unseguimiento de ella; Qt es quien lo hace y la borrará automáticamente cuando el objetoMyWdiget sea destruido (No hay nada malo en borrar un hijo cuando lo desees, el hijoavisará automáticamente a Qt de su muerte inmediatamente).

La llamada a QWidget ::setGeometry () establece la posición y el tamaño del widget en la pantalla. Es equivalente a llamar a QWidget ::move () seguido de QWidget::resize.

  connect ( quit  , SIGNAL( clicked ()), qApp , SLOT ( quit ())); }

El puntero qApp es una variable global declarada en el fichero cabecera QApplication, yapunta a la instancia única de QApplication en la aplicación.

int main( int argc , char  *argv[]){   QApplication app( argc , argv );

MyWidget widget ;

8/4/2019 46172282 Tutorial de Qt

http://slidepdf.com/reader/full/46172282-tutorial-de-qt 9/47

widget. show();  return app.exec(); }

Instanciamos nuestro nuevo hijo, lo mostramos y ejecutamos la aplicación.

Ejecutar la aplicación.El comportamiento del programa es muy similar al del capítulo anterior , la diferencia resideen la manera en la que lo hemos implementado. Aunque no son exactamente iguales. Por ejemplo, intenta redimensionar la ventana para verlo.

Ejercicios.Intenta crear otro objeto MyWidget en main(), ¿Qué ocurre?.Prueba a añadir mas botones o a incluir otros widgets a parte de QPushButton.

ResumenEn el quinto capítulo del tutorial vamos a ver como crear y conectar varios widgets entreellos usando signals y slots, y como manejar el redimensionado de varios widgets ennuestra aplicación.

#include <QApplication>

#include <QFont>#include <QLCDNumber>#include <QPushButton>#include <QSlider>#include <QVBoxLayout>#include <QWidget>

class MyWidget :  public QWidget {    public:

MyWidget ( QWidget  * parent = 0 );

 };

MyWidget ::MyWidget ( QWidget  * parent  )  : QWidget (  parent  ){   QPushButton *quit = new  QPushButton( tr ( "Quit"  ));

quit -> setFont ( QFont ( "Times"  , 18 , QFont :: Bold  ));

  QLCDNumber  *lcd = new  QLCDNumber ( 2 );

8/4/2019 46172282 Tutorial de Qt

http://slidepdf.com/reader/full/46172282-tutorial-de-qt 10/47

lcd -> setSegmentStyle( QLCDNumber :: Filled  );

  QSlider  * slider = new  QSlider ( Qt :: Horizontal  );slider -> setRange( 0 , 99 );slider -> setValue( 0 );

  connect ( quit  , SIGNAL( clicked ()), qApp , SLOT ( quit ()));  connect (  slider  , SIGNAL( valueChanged ( int  )),

lcd  , SLOT ( display( int  )));

  QVBoxLayout  *layout = new QVBoxLayout ;layout ->addWidget ( quit  );layout ->addWidget ( lcd  );layout ->addWidget (  slider  );setLayout ( layout  );

 }

int main( int argc , char  *argv[]){   QApplication app( argc , argv );

MyWidget widget ;widget. show();

  return app.exec(); }

Explicación

class MyWidget :  public QWidget { 

   public:MyWidget ( QWidget  * parent = 0 );

 };

MyWidget ::MyWidget ( QWidget  * parent  )  : QWidget (  parent  ){   QPushButton *quit = new  QPushButton( tr ( "Quit"  ));

quit -> setFont ( QFont ( "Times"  , 18 , QFont :: Bold  ));

  QLCDNumber  *lcd = new  QLCDNumber ( 2 );

lcd -> setSegmentStyle( QLCDNumber :: Filled  );lcd es un QLCDNumber : un widget que muestra un número como si fuera un LCD. Vamosa hacer que lcd muestre dos dígitos y estableceremos la propiedadQLCDNumber ::segmentStyle a QLCDNumber::Filled para que sea mas legible.

  QSlider  * slider = new  QSlider ( Qt :: Horizontal  );slider -> setRange( 0 , 99 );slider -> setValue( 0 );

8/4/2019 46172282 Tutorial de Qt

http://slidepdf.com/reader/full/46172282-tutorial-de-qt 11/47

El usuario puede usar un QSlider para ajustar un valor entero dentro de un rango. Con estastres instrucciones creamos un slider horizontal, establecemos su rango de 0 a 99 y su valor inicial a 0.

  connect (  slider  , SIGNAL( valueChanged ( int  )),lcd  , SLOT ( display( int  )));

Usamos el mecanismo de signals y slots para conectar la señal valueChanged( ) del slider alslot display() del LCD.

Cada vez que el valor del slide cambie, este emitirá el nuevo valor lanzando la signalvalueChanged( ). Como esta señal está conectada al slot display( ) del LCD, se llamará alslot cuando la señal sea emitida. Ten en cuenta que ninguno de los objetos sabe sobre elotro (esencial en la programación con componentes).

Por otra parte, los slots son funciones miembro normales y siguen las reglas de accesonormal en C++.

  QVBoxLayout  *layout = new QVBoxLayout ;layout ->addWidget ( quit  );

layout ->addWidget ( lcd  );layout ->addWidget (  slider  );setLayout ( layout  );

MyWidget ahora usa un QVBoxLayout para manejar la geometría de sus widgets hijos. Por esta razón ya no necesitamos especificar las coordenadas en la pantalla para cada widgethijo tal como hicimos en el capítulo 4. Además, usar un layout asegura que seredimensionen los widgets hijos cuando la ventana se redimensione. Por tanto añadimos loswidgets quit , lcd y slider al layout mediante QBoxLayout ::addWidget ().

La función QWidget ::setLayout () establece el layout de MyWidget . Esto hace que el layoutsea hijo de MyWidget, por lo que no tenemos que preocuparnos de borrarlo, la relación padre-hijo asegura que será borrado junto a MyWidget . Además, la llamada

QWidget ::setLayout () ajusta automaticamente los widgets en el layout como hijos deMyWidget . Por eso no tenemos que especificar this como padre en los widgets quit , lcd y slider .

En Qt, los widgets pueden ser hijos de otros widgets (por ejemplo mediante this) o puedenno tener padre. Un widget se puede añadir a un layout, lo cual hace que el layout sea elresponsable de manejar la geometría de dicho widget, pero el layout nunca puede actuar como un padre en si. Es mas, el constructor de QWidget toma un puntero a QWidget como padre, y QLayout no hereda de QWidget.

Ejecutar la aplicación.El LCD de números refleja los cambios hechos en el slider, y los widgets se redimensionan

de forma correcta. Date cuenta de que el widget LCD cambia de tamaño cuando se cambiael tamaño de la ventana (porque puede), pero los otros siguen teniendo el mismo tamaño (locontrario sería sería extraño).

Ejercicios.Intenta cambiar el LCD añadiendo mas dígitos o cambiando el modo(QLCDNumber ::setMode ()). Incluso puedes añadir cuatro botones para establecer la basedel número (decimal, hexadecimal, octal o binaria).

8/4/2019 46172282 Tutorial de Qt

http://slidepdf.com/reader/full/46172282-tutorial-de-qt 12/47

También puedes probar a cambiar el rango del slider.¿Tal vez hubiera sido mejor usar un QSpinBox en vez de un slider?Intenta hacer que la aplicación se cierre si se produce un desbordamiento en el LCD.

Otra Guia:

Tutorial de Qt 4: Nuestro primer programa, “Hola Mundo”En este artículo vamos a crear y explicar a detalle la clásica primera aplicación en programación, esta vez con Qt.

El código de un Hola Mundo en Qt es el siguiente

123456 7 8

9101112

#include <QApplication> #include <QLabel>  int main(int argc, char  *argv []){QApplication app(argc, argv );QLabel *label =  new QLabel("Hola Mundo!");

 

label-> show (); return app.exec();

}

12

#include <QApplication> #include <QLabel> 

Incluimos los archivos de cabecera que utilizaremos para el ejemplo, QApplication es unaclase que representa una aplicación gráfica de Qt, es la encargada de administrar el flujo deejecución y la configuración principal de la aplicación. QLabel es una clase que representaa un control de interfaz de usuario etiqueta, el cual es generalmente utilizado para mostrar texto no editableen pantalla.

4 int main(int argc, char  *argv [])

Declaramos nuestra función main en la cual comenzará la ejecución de nuestro programa,es necesario especificar los argumentos de línea de comandos argc (un entero que contieneel número de argumentos) y argv (un arreglo/matriz que contiene el valor de cada uno delos argumentos) ya que al crear un objeto de la clase QApplication es necesarioespecificarlos.

6 QApplication app(argc, argv );

Crea el objeto QApplication llamado app y pasa como parámetros los argumentos de líneade comandos.

7 QLabel *label =  new QLabel("Hola Mundo!");

Crea un apuntador a un objeto QLabel llamado label, y lo inicializa con la sentencia newQLabel(“Hola Mundo!”), la cual reserva memoria para la etiqueta que contendrá el textoque queremos mostrar en pantalla, el cual especificamos como argumento del constructor.Es conveniente crear la variable label como apuntador ya que de esta forma Qt se harácargo de gestionar la memoria asignada a este elemento.

9 label-> show ();

8/4/2019 46172282 Tutorial de Qt

http://slidepdf.com/reader/full/46172282-tutorial-de-qt 13/47

Muestra la etiqueta en pantalla. Qt se encargará de crear una ventana para poder mostrar laetiqueta en pantalla ya que nosotros no hemos asignado alguna.

11 return app.exec();

Inicia el hilo principal de la aplicación a partir de este momento el framework toma elcontrol de la aplicación y responde a la interacción del usuario con los controles de interfaz

gráfica de acuerdo a todo lo especificado anteriormente. La sentencia return regresa alsistema operativo la respuesta de la ejecución del programa una vez que ha finalizado, estárespuesta tipicamente será cero en caso de que la aplicación se haya ejecutadoexitosamente.

Compilación y Ejecución

Guardamos el archivo como holamundo.cpp o cualquier otro nombre con extensión “.cpp”.Abrimos una terminal en la ubicación de nuestro archivo holamundo.cpp y ejecutamos lossiguientes comandos.

qmake -project

Crea un archivo de proyecto para nuestra aplicación

qmake holamundo.pro

Crea un archivo de proyecto específico para la plataforma o SO en el que estamostrabajando

 make

Generar un archivo ejecutable correspondiente a nuestra aplicación.

./ holamundo

Ejecuta el archivo ejecutable generado por el compilador al procesar nuestro código.

Si todo ha ido bien deberías ver una ventana parecida a la siguiente

Tutorial de Qt4: Diálogos, comunicación con el usuario

(Parte II)

En el artículo anterior revisamos la primera de las dos formas principales de utilizar diálogos en Qt, esto es creando clases que hereden de QDialog, implementando lafuncionalidad de estas clases y gestionando las respuestas que recibimos a través de lafunción QDialog::exec()

8/4/2019 46172282 Tutorial de Qt

http://slidepdf.com/reader/full/46172282-tutorial-de-qt 14/47

En este artículo veremos la segunda forma de utilizar diálogos en una aplicación de Qt, estoes, utilizando las clases de diálogos estándar que nos proporciona Qt, estas clases son:

• QMessageBox Permite mostrar mensajes de notificación al usuario.

• QFileDialog Permite mostrar un diálogo que sirve para seleccionar unarchivo o carpeta del sistema de archivos.

• QInputDialog Permite mostrar un diálogo con un widget para que elusuario puede introducir información.

• QColorDialog Muestra un diálogo para que el usuario pueda seleccionarun color.

• QPrintDialog Muestra un diálogo para especificar configuraciones de laimpresora.

A continuación mostraremos un ejemplo de uso de estos diálogos mediante unatraducción/adaptación de el ejemplo Standar Dialogs de la documentación oficial de Qt,esta documentación la podemos encontrar en la dirección: http://qt.nokia.com/doc/4.6

El ejemplo se compone de los siguientes archivos:

• Ventana.h

• Ventana.cpp

• main.cpp

Los archivos Ventana.h y Ventana.cpp componen la clase Ventana, la cual representa laventana principal de la aplicación de ejemplo. Esta clase esta compuesta por dos columnasde widgets, una de ellas está compuesta por botones; Cada uno de ellos servirá para mostrar un diálogo estándar que nos permitirá obtener un dato del usuario. La segunda columna secompone de etiquetas y en cada una de ellas escribiremos la información que proporcionóel usuario a través del diálogo correspondientes. Dicha ventana se muestra en la siguienteimagen.

A continuación explicamos el código del archivo Ventana.cpp:

1

2

3

4

#include "ventana.h"#include <QPushButton> #include <QLabel> #include <QGridLayout> 

8/4/2019 46172282 Tutorial de Qt

http://slidepdf.com/reader/full/46172282-tutorial-de-qt 15/47

5

6

7

8

9

10

11

12

13

14

 #include <QInputDialog> #include <QColorDialog> #include <QFileDialog> #include <QFontDialog> #include <QMessageBox> #include <QErrorMessage>  Ventana::Ventana(){

QGridLayout* layoutPrincipal =  new QGridLayout;

De las líneas 1 a 11 incluimos los archivos de cabecera que necesitamos para este ejemplo.En la línea 13 comienza el constructor de nuestra clase. En la línea 15 declaramos el layoutcon el que organizamos los componentes de nuestra ventana.

17 1819

botonObtenerTexto =  new QPushButton(trUtf8("Obtener Texto"));botonObtenerEntero =  new QPushButton(trUtf8("Obtener Entero"));

  (...)

3233

3435

etiquetaObtenerTexto =  new QLabel(trUtf8("\t\t\t\t"));etiquetaObtenerEntero =  new QLabel(trUtf8("\t\t\t\t"));

etiquetaObtenerDoble =  new QLabel(trUtf8("\t\t\t\t

"));  (...)

De las líneas 17 a 45 creamos los widgets que utilizaremos en el ejemplo. No mostramostodas las líneas debido a que el código es muy repetitivo y las líneas son muy similares. Endónde escribimos (…) van líneas iguales a las anteriores pero para los demás widgets. Elcódigo del ejemplo se puede descargar mediante los links de la parte inferior de esteartículo.

A partir de la línea 17 creamos los botones que servirán para mostrar cada uno de losdiálogos estándar de Qt. A partir de la línea 32 y hasta la 45 creamos las etiquetas en lasque escribiremos el valor de retorno de cada uno de los diálogos.

47 

484950

etiquetaObtenerTexto-> setFrameStyle(QFrame::Box );

etiquetaObtenerEntero-> setFrameStyle(QFrame::Box );etiquetaObtenerDoble-> setFrameStyle(QFrame::Box );

  (...)

62636465

layoutPrincipal-> addWidget(botonObtenerTexto, 0, 0);layoutPrincipal-> addWidget(etiquetaObtenerTexto, 0, 1);layoutPrincipal-> addWidget(botonObtenerEntero, 1, 0);

  (...)

93949596 

connect(botonObtenerTexto, SIGNAL(clicked ()), this,SLOT (obtenerTexto()));

connect(botonObtenerEntero, SIGNAL(clicked ()), this,SLOT (obtenerEntero()));

connect(botonObtenerDoble, SIGNAL(clicked ()), this,SLOT (obtenerDoble()));  (...)

De las líneas 47 a 60 establecemos un marco para las etiquetas que mostrarán la respuestade los diálogos. En las líneas 62 a 89 configuramos la apariencia de la interfaz de usuarioutilizando un QGridLayout. Y finalmente, de las líneas 93 a 106 conectamos cada botóncon su slot correspondiente, cada slot mostrará un diálogo distinto para cada botón y procesará la respuesta del usuario.

8/4/2019 46172282 Tutorial de Qt

http://slidepdf.com/reader/full/46172282-tutorial-de-qt 16/47

A partir de la línea 109 comienza la implementación de los slots, en todos ellos realizamoslas siguiente acciones:

1. Creamos una variable para almacenar la información que ingresa elusuario por medio del diálogo.

2. Ejecutamos el diálogo para obtener la información del usuario y el valor

de respuesta, este último está determinado por el botón que presiona elusuario.

3. Evaluamos el valor de respuesta del diálogo.

4. Dependiendo del valor de la respuesta decidimos de que maneraprocesar la información capturada, si es que la hay.

A continuación revisamos los slots que conectamos con cada uno de los botones,comenzaremos con los slots que hacen uso de los diálogos que nos ofrece la claseQInputDialog.

109110111112113114115116 117 118119120121

122123124125126 127 128129130131132133134135136 137 138

void Ventana::obtenerTexto(){

QString texto = QInputDialog ::getText(this, trUtf8(""),trUtf8(""), QLineEdit::Normal, trUtf8(""), &ok); 

if (ok)etiquetaObtenerTexto-> setText(texto);

} void Ventana::obtenerEntero(){

int entero = QInputDialog ::getInt(this, trUtf8(""),trUtf8(""), 42, 41, 43, 1, &ok);

if (ok)etiquetaObtenerEntero-

> setText(QString ::number (entero));

} void Ventana::obtenerDoble(){

double doble = QInputDialog ::getDouble(this, trUtf8(""),trUtf8(""), 9.9, 5, 15, 2, &ok);

if (ok)etiquetaObtenerDoble-> setText(QString ::number (doble));

} void Ventana::obtenerElemento(){

QStringList listaElementos;listaElementos <<  "Elemento 1" <<  "Elemento 2" <<  "Elemento

3";QString elemento = QInputDialog ::getItem(this, trUtf8(""),

trUtf8(""), listaElementos, 0, false, &ok);if (ok)

etiquetaObtenerElemento-> setText(elemento);}

8/4/2019 46172282 Tutorial de Qt

http://slidepdf.com/reader/full/46172282-tutorial-de-qt 17/47

De la línea 109 a la 115 implementamos el slot obtenerTexto, en él mostramos un diálogoque nos permitirá obtener un valor de texto capturado por el usuario. Este diálogo loejecutamos mediante la función

QString QInputDialog ::getText ( QWidget * parent, const QString & title,const QString & label, QLineEdit::EchoMode mode = QLineEdit::Normal,const QString & text = QString (), bool * ok =  0, Qt::WindowFlags flags = 

0 )

Está función recibe como parámetros:

• Un apuntador al widget que deseamos establecer como su padre.

• El texto que se mostrará en la barra de título del diálogo.

• El texto que mostrará el diálogo.

• El modo (EchoMode) en el que se mostrará el texto ingresado. Aquipodemos establecer un valor de la enumeración EchoMode el cualindicará si el texto debe ser visible, que no se muestre o que semuestren caracteres para enmascarar contraseñas (como asteriscos)

• El valor predeterminado que se mostrará en el campo de texto

• Un apuntador a una variable que almacena el valor que indica que botónfue presionado.

• Las flags (banderas u opciones) del diálogo, las cuales establecenpropiedades del sistema de ventanas para un widget, como los botonesque se muestran en la barra de título o si debe mostrar barra de título ono. Los valores posibles son parte de la enumeración Qt::WindowFlags

Si el usuario no cierra el diálogo y en cambio presiona algún botón, entonces escribimos elvalor de la respuesta en la etiqueta correspondiente.

De la línea 117 a 122 implementamos el slot obtenerEntero, en él mostramos un diálogoque contiene una spinBox que permitirá al usuario establecer un valor numérico entero.Este diálogo lo ejecutamos mediante la función

int QInputDialog ::getInt ( QWidget * parent, const QString & title, const

QString & label, int value =  0, int min =  -2147483647 , int max = 2147483647 , int step =  1, bool * ok =  0, Qt::WindowFlags flags =  0 )

8/4/2019 46172282 Tutorial de Qt

http://slidepdf.com/reader/full/46172282-tutorial-de-qt 18/47

Los primeros tres y los dos últimos parámetros de está “familia” de funciones y de algunosde los otros diálogos estándar son iguales, indican el widget padre, el título del diálogo, eltexto que se mostrará en el diálogo, un apuntador a la variable donde se almacenará larespuesta al diálogo y una lista de flags u opciones del diálogo.

A partir del cuarto parámetro y en orden, los parámetros específicos de este diálogo son:

• El valor predeterminado que al que se establecerá la spinbox cuando semuestre el diálogo

• El valor mínimo al que se puede establecer el valor de la spinbox

• El valor máximo al que se puede establecer el valor de la spinbox

• La cantidad en que se incrementará o decrementará el valor de laspinbox al presionar las flechas del extremo (step o paso)

De las líneas 124 a 129 implementamos el slot obtenerDoble, en él mostramos un diálogomuy similar al que del slot obtenerEntero con la diferencia de que el valor de la spinbox podrá ser un valor decimal o de punto flotante de doble precisión. Este diálogo loejecutamos mediante la función

double QInputDialog ::getDouble ( QWidget * parent, const QString & title,const QString & label, double value =  0, double min =  -2147483647 , doublemax =  2147483647 , int decimals =  1, bool * ok =  0, Qt::WindowFlags flags=  0 )

Los parámetros de esta función son muy similares a la función getInt salvo por el séptimo parámetro, el cuál indica el número de decimales del número, el valor por defecto es deuno.

8/4/2019 46172282 Tutorial de Qt

http://slidepdf.com/reader/full/46172282-tutorial-de-qt 19/47

De la línea 131 a 138 implementamos el slot obtenerElemento, en él mostramos un diálogoque contiene una comobox que permite al usuario elegir un valor de una lista queindiquemos. Este diálogo lo ejecutamos mediante la función

QString QInputDialog ::getItem ( QWidget * parent, const QString & title,const QString & label, const QStringList & items, int current =  0, booleditable =  true, bool * ok =  0, Qt::WindowFlags flags =  0 )

Esta función recibe del cuarto al sexto parámetro:• Una lista de cadenas de texto que serán los elementos de la combobox

• La posición del elemento seleccionado por defecto, si no se especificaserá cero

• Un valor booleano que indica si la combobox será editable

140141142143144145

146 147 148149150151152153154155

void Ventana::obtenerColor (){

QColor color = QColorDialog ::getColor ();if (color.isValid ()) {

etiquetaObtenerColor -> setText(color.name());etiquetaObtenerColor -> setPalette(QPalette(color ));

etiquetaObtenerColor -> setAutoFillBackground (true);}

} void Ventana::obtenerFuente(){

QFont fuente = QFontDialog ::getFont(&ok);if (ok)

etiquetaObtenerFuente-> setText(fuente.toString ());}

De las líneas 140 a 148 implementamos el slot obtenerColor, en el mostramos un diálogoque contiene controles especializados para permitir que el usuario eliga un color. Estediálogo lo mostramos mediante la función

QColorDialog ::getColor ( const QColor & initial, QWidget * parent, constQString & title, ColorDialogOptions options =  0 )

8/4/2019 46172282 Tutorial de Qt

http://slidepdf.com/reader/full/46172282-tutorial-de-qt 20/47

Esta función recibe como parámetros:

• Un objeto de la clase QColor que indica el color inicial que se estableceráen el diálogo, si no se especifica ninguno el color blanco será elseleccionado

• El widget padre del diálogo

• El título del diálogo

• Miembros de la enumeración ColorDialogOptions, que permitenestablecer algunas propiedades del diálogo como mostrar canal alfa ousar el diálogo nativo del sistema operativo

De la línea 150 a 155 implementamos el slot obtenerFuente, el cual muestra un diálogo queincluye controles especiales para que el usuario pueda seleccionar una fuente para el texto.Dicho diálogo se muestra mediante la función

QFont QFontDialog ::getFont(bool *ok, QWidget * parent)

Dicha función tiene múltiples sobrecargas en las cuales se pueden establecer valoresiniciales y configuraciones del diálogo similares a las de los diálogos anteriores pero en esteejemplo utilizamos una función que sólo recibe como parámetros el apuntador a la variableque almacena la respuesta que da el usuario al diálogo y un apuntador al widget padre deeste diálogo.

8/4/2019 46172282 Tutorial de Qt

http://slidepdf.com/reader/full/46172282-tutorial-de-qt 21/47

157 158159160161162163164165166 167 168169170171172173174175176 

177 178179180181182183184185186 187 188189190191192193194195196 197 198199

void Ventana::obtenerDirectorioExistente(){

QString directorio = QFileDialog ::getExistingDirectory (this,trUtf8(""), etiquetaObtenerDirectorioExistente-> text(),QFileDialog ::ShowDirsOnly );

if (!directorio.isEmpty ())etiquetaObtenerDirectorioExistente-

> setText(directorio);} void Ventana::obtenerArchivoAbrir (){

QString filtroSeleccionado;QString Nombre = QFileDialog ::getOpenFileName(this,

trUtf8(""),

etiquetaObtenerArchivoAbrir -> text(),

trUtf8("Todos los archivos (*);;Archivos de Cabecera C/C++

(*.h);;Archivos de Código Fuente C++ (*.cpp)"),

&filtroSeleccionado, 0);if  (!Nombre.isEmpty ())

etiquetaObtenerArchivoAbrir -> setText(Nombre);} void Ventana::obtenerArchivosAbrir (){

QStringList archivos = QFileDialog ::getOpenFileNames(this,

trUtf8(""),"",

trUtf8("Todos los Archivos (*);;Archivos de Cabecera C/C++(*.txt);;Archivos de Código Fuente C++ (*.cpp)")); 

if  (archivos.count()) {etiquetaObtenerArchivosAbrir -

> setText(QString ("[%1]").arg (archivos.join(", ")));}

} void Ventana::obtenerArchivoGuardar (){

QString nombreArchivo = QFileDialog ::getSaveFileName

(this,

trUtf8(""),

etiquetaObtenerArchivoGuardar -> text(),

trUtf8("Todos los Archivos (*);;Archivos de Cabecera C/C++(*.txt);;Archivos de Código Fuente C++ (*.cpp)")); 

if  (!nombreArchivo.isEmpty ())

8/4/2019 46172282 Tutorial de Qt

http://slidepdf.com/reader/full/46172282-tutorial-de-qt 22/47

etiquetaObtenerArchivoGuardar -> setText(nombreArchivo);}

De las líneas 157 a 207 implementamos los slots que hacen uso de las funciones estáticasde la clase QFileDialog.

De la línea 157 a 162 implementamos el slot obtenerDirectorioExistente en el cual

ejecutamos un diálogo que mostrará una ventana de exploración del sistema de archivos yque nos permitirá seleccionar una carpeta o directorio. Este diálogo lo mostramos con lafunción

QString getExistingDirectory ( QWidget * parent =  0, const QString &caption = QString (), const QString & dir = QString (), Options options = ShowDirsOnly )

Esta función recibe como parámetros

• Un apuntador al widget padre del diálogo

• El título del diálogo

• La ruta del directorio en dónde se desea comenzar a buscar

• Miembros de la enumeración QFileDialog::Options que permitenconfigurar opciones del diálogo como el sólo mostrar directorios outilizar un diálogo no nativo

De la línea 176 a 187 implementamos el slot obtenerArchivoAbrir el cual funciona demanera muy similar al slot anterior con la diferencia de que este permite seleccionar unarchivo en lugar de un directorio. Mostramos el diálogo utilizado en este slot con la función

QString QFileDialog ::getOpenFileName ( QWidget * parent =  0, constQString & caption = QString (), const QString & dir = QString (), constQString & filter = QString (), QString * selectedFilter =  0, Optionsoptions =  0 )

8/4/2019 46172282 Tutorial de Qt

http://slidepdf.com/reader/full/46172282-tutorial-de-qt 23/47

En esta función el último y los tres primeros parámetros son iguales al de la función del slotanterior. Los parámetros propios de esta función son:

• Como cuarto parámetro, una cadena que representa los filtros quepodrán ser aplicados al diálogo, este filtro determina que tipo de archivose muestra. Para cada tipo de archivo se escribe una descripción y entreparéntesis la extensión del tipo de archivo. Separamos cada tipo de

archivo mediante dos caracteres punto y coma (;;).

• Como quinto parámetro, una cadena que indique el filtro seleccionadoactualmente.

De la línea 176 a la 187 implementamos el slot obtenerArchivosAbrir el cual muestra undiálogo casi igual al del slot anterior con la diferencia de que este permite al usuarioseleccionar más de un archivo. Mostramos el diálogo utilizado en este slot con la función

QStringList QFileDialog ::getOpenFileNames ( QWidget * parent =  0,const QString & caption = QString (), const QString & dir = QString (),const QString & filter = QString (), QString * selectedFilter =  0, Optionsoptions =  0 )

Los parámetros de la función utilizada para ejecutar el diálogo son iguales a los de lafunción utilizada para abrir un solo archivo.

De la línea 189 a 199 implementamos el slot obtenerArchivoGuardar el cual muestra undiálogo que permite guardar un archivo al usuario y eligiendo su ubicación y especificandosu nombre. El diálogo utilizado en este slot lo ejecutamos mediante la función

QString QFileDialog ::getSaveFileName ( QWidget * parent =  0, constQString & caption = QString (), const QString & dir = QString (), constQString & filter = QString (), QString * selectedFilter =  0, Optionsoptions =  0 )

8/4/2019 46172282 Tutorial de Qt

http://slidepdf.com/reader/full/46172282-tutorial-de-qt 24/47

Los parámetros de esta función son iguales que los de la función utilizada para ejecutar eldiálogo que permite abrir archivos. Si especificamos un nombre que coincida con el de unarchivo existente se mostrará otro diálogo solicitando la confirmación del usuario, estediálogo muestra dos botones de respuesta: Aceptar y Cancelar.

201202203204205206 207 208209210211212213214215

216 217 218219220221222223224225226 227 228229230231232233234235236 237 238

void Ventana::mostrarMensajeCritico(){

QMessageBox ::StandardButton respuesta = QMessageBox ::critical(this,trUtf8(""),trUtf8(""),QMessageBox ::Abort | QMessageBox ::Retry  |

QMessageBox ::Ignore); 

if  (respuesta == QMessageBox ::Abort)etiquetaMostrarMensajeCritico-> setText(tr ("Abortar"));

else if  (respuesta == QMessageBox ::Retry )etiquetaMostrarMensajeCritico-

> setText(tr ("Reintentar"));else

etiquetaMostrarMensajeCritico-> setText(tr ("Ignorar"));} void Ventana::mostrarMensajeInformacion(){

QMessageBox ::StandardButton respuesta;respuesta = QMessageBox ::information(this, trUtf8(""),

trUtf8("Este es un mensaje de información"));if  (respuesta == QMessageBox ::Ok)

etiquetaMostrarMensajeInformacion-> setText(tr ("OK"));else

etiquetaMostrarMensajeInformacion-> setText(tr ("Escape"));} void Ventana::mostrarMensajePregunta(){

QMessageBox ::StandardButton respuesta;respuesta = QMessageBox ::question(this, trUtf8(""),

trUtf8("Este es un mensaje con una pregunta"),

QMessageBox ::Yes | QMessageBox ::No | QMessageBox ::Cancel);

8/4/2019 46172282 Tutorial de Qt

http://slidepdf.com/reader/full/46172282-tutorial-de-qt 25/47

239240241242243244245246 247 248249250251

if  (respuesta == QMessageBox ::Yes)etiquetaMostrarMensajePregunta-> setText(tr ("Sí"));

else if  (respuesta == QMessageBox ::No)etiquetaMostrarMensajePregunta-> setText(tr ("No"));

elseetiquetaMostrarMensajePregunta-

> setText(tr ("Cancelar"));} void Ventana::mostrarMensajeAdvertencia(){

QMessageBox msgBox (QMessageBox ::Warning ,trUtf8("QMessageBox::warning()"),

trUtf8("Este es un mensaje deadvertencia"), 0, this);

msgBox.addButton(trUtf8("Guardar Otra Vez"),QMessageBox ::AcceptRole);

msgBox.addButton(trUtf8("Continuar"),QMessageBox ::RejectRole);

if  (msgBox.exec() == QMessageBox ::AcceptRole)

etiquetaMostrarMensajeAdvertencia-> setText(tr ("Guardar Otra Vez"));

elseetiquetaMostrarMensajeAdvertencia-

> setText(tr ("Continuar"));}

A partir de la línea 201 y hasta el fin del archivo en la línea 251 implementamos los slotsque muestran los diálogos de la case QMessageBox. Entre las líneas 201 y 215implementamos el slot mostrarMensajeCritico el cual permite mostrar un diálogo con unicono de error que normalmente sirve para indicar que ocurrió algún error grave en laaplicación. Mostramos este diálogo mediante la función

StandardButton QMessageBox ::critical ( QWidget * parent, const QString &

title, const QString & text, StandardButtons buttons = Ok, StandardButtondefaultButton = NoButton )

Dicha función nos devuelve un valor de la enumeración StandarButttons, la cual contienetodos los posibles valores que devuelve un diálogo al presionar cada uno de los botonesdisponibles, como: Aceptar, Cancelar, Reintentar, Sí, Sí a todo, No, Cancelar.

Las cuatro funciones de la clase QMessageBox que revisaremos y que nos sirven paramostrar un diálogo de información reciben los mismos parámetros, los cuales son:

• Un apuntador al widget padre del diálogo

• El título del diálogo

8/4/2019 46172282 Tutorial de Qt

http://slidepdf.com/reader/full/46172282-tutorial-de-qt 26/47

• El texto que deseamos mostrar en el diálogo

• Una lista de valores de la enumeración StandarButton separadados porcaracteres 2de barra”, (el que se usa para un OR a nivel bit en C/C++)en donde cada valor indica que se debe mostrar su botóncorrespondiente

• Un valor de la enumeración StandarButtons el cual indica que botón seestablecerá como predeterminado, es decir sobre cual se hará unefectro de clic al presionar la tecla enter al estar el diálgo activo

Entre las líneas 217 y 225 implementamos el slot mostrarMensajeInformacion en el cualmostramos un diálogo que sirve para mostrar información al usuario, como un aviso sobrela conclusión de una tarea o una notificación de algún evento. Mostramos el diálogoutilizado mediante la función

StandardButton QMessageBox ::information ( QWidget * parent, const QString & title, const QString & text, StandardButtons buttons = Ok,StandardButton defaultButton = NoButton )

De la línea 227 a 239 implementamos el slot mostrarMensajePregunta en el cual mostramosun diálogo con icono de un signo de interrogación, este diálogo sirve para realizar una pregunta al usuario o solicitar su confirmación u aprobación para un proceso, como al

guardar o borrar un archivo. Mostramos este diálogo mediante la funciónStandardButton QMessageBox ::question ( QWidget * parent, const QString &title, const QString & text, StandardButtons buttons = Ok, StandardButtondefaultButton = NoButton )

Y finalmente de le la línea 241 a la 251 implementamos el slot mostrarMensajeAdvertenciaen el cual mostramos un diálogo con que sirve para mostrar un mensaje de advertencia,como información sobre un error poco grave. Este diálogo lo mostramos mediante lafunción

StandardButton QMessageBox ::warning  ( QWidget * parent, const QString &title, const QString & text, StandardButtons buttons = Ok, StandardButtondefaultButton = NoButton )

8/4/2019 46172282 Tutorial de Qt

http://slidepdf.com/reader/full/46172282-tutorial-de-qt 27/47

Con esa función concluimos la revisión del código del archivo Ventana.cpp. En el archivomain.cpp simplemente creamos un objeto de esta clase y lo mostramos en pantalla.

Eso es todo en este artículo. En la siguiente parte de este tutorial veremos como utilizar loswidgets QListWidget, QTableWidget y QTreeWidget, los cuales nos permiten visualizar unconjunto de datos a manera de lista, tabla o árbol de manera sencilla. Estos widgets son parte del framework modelo/vista que Qt provee.

Tutorial de Qt 4: QMainWindow, la ventana principal de la

aplicación

En el artículo anterior de este tutorial vimos como implementar la funcionalidad de unaaplicación gráfica de Qt utilizando señales y slots. En este artículo revisaremos a detalle unwidget especial, QMainWindow, el cuál posee características especiales para ser utilizadocomo la ventana principal de las aplicaciones Qt. La estructura de la QMainWindow se puede ver en la siguiente imagen

Una QMainWindow puede estar compuesta de las siguientes cinco áreas o secciones:

• Menu Bar como su nombre lo indica esta barra contiene menús, los

cuales están compuestos por elementos de texto o etiquetas que indicanlas acciones que puede realizar la aplicación y que se ejecutan al hacerclic sobre ellas. Normalmente sólo existe una de ellas en la ventana yestá colocada en la parte superior, debajo de la barra de título. Algunosejemplos muy conocidos de menús que suelen colocarse en esta barrason Archivo, Edición, Herramientas o Ayuda.

8/4/2019 46172282 Tutorial de Qt

http://slidepdf.com/reader/full/46172282-tutorial-de-qt 28/47

• Toolbars al igual que la barra de menús, esta clase de barras, conocidacomo barra de herramientas está compuesta por las acciones que puederealizar la aplicación, con la diferencia de que en esta barra dichasacciones se muestran mediante iconos en lugar de etiquetas. Estasbarras suelen estar ubicadas debajo de la barra de menús y podemosencontrar una o más de estas barras en una ventana. Un ejemplo muyconocido de iconos colocados en este tipo de barras son los de Guardar,representado por un diskette o Imprimir, representado por unaimpresora.

• Status Bar Esta barra, conocida como barra estatus o de estado,normalmente está colocada en la parte inferior de la ventana, en ella semuestran mensajes informativos sobre el estado de la aplicación, lasacciones que está realizando o la descripción del elemento al queestemos apuntando con el mouse.

• Dock Widgets Este es un tipo de widgets que pueden ser acoplados oajustados alrededor del widget central de una aplicación o permitir que“floten” libremente en el escritorio, al igual que las barras deherramientas contienen iconos y botones que permiten ejecutar

acciones que proporciona la aplicación.

8/4/2019 46172282 Tutorial de Qt

http://slidepdf.com/reader/full/46172282-tutorial-de-qt 29/47

• Central Widget Este widget representa el área de trabajo de unaaplicación, como la tabla de celdas de una aplicación en hoja de cálculoo el área de texto de un procesador de textos.

Podemos reconocer estás secciones en un buen número de aplicaciones, como ejemplo presentamos la ventana de Open Office Writer (clic para ampliar).

A continuación mostraremos un sencillo ejemplo de una aplicación que basada en unaQMainWindow, la cual contendrá una etiqueta como widget central la cual cambiará eltexto que muestra dependiendo de la acción que ejecutemos, estas acciones se encontraránen una barra de menús y una barra de herramientas también incluiremos una barra deestatus.

La aplicación está compuesta por los siguientes tres archivos:

• ventanaprincipal.h es el archivo de encabezado de la claseVentanaPrincipal, contiene la declaracion de las variables y la definiciónde las funciones que utilizaremos en esta aplicación.

• ventanaprincipal.cpp es el archivo fuente de la claseVentanaPrincipal, contiene la implementación de las funciones

declaradas en el archivo de encabezado.• main.cpp

A continuación revisaremos a detalle los archivos de la aplicación, sólo explicaremos lassecciones que no hayan sido revisadas en partes anteriores de este tutorial o que seanrelevantes en este contexto

ventanaprincipal.h

12345

6 7 891011121314

#ifndef VENTANAPRINCIPAL_H #define VENTANAPRINCIPAL_H  #include <QMainWindow>  

class QLabel;class QToolBar ;class QAction;class QMenu; class VentanaPrincipal :  public QMainWindow {Q_OBJECT  

8/4/2019 46172282 Tutorial de Qt

http://slidepdf.com/reader/full/46172282-tutorial-de-qt 30/47

1516 17 181920212223242526 27 28293031323334

 public:VentanaPrincipal();

  private slots:  void accionNuevoLanzada();  void accionAbrirLanzada();  void accionAcercaDeLanzada();  void accionSalirLanzada(); 

 private:QMenu* menuArchivo;QMenu* menuAyuda;QToolBar * barraDeHerramientas;QAction* accionNuevo;QAction* accionAbrir ;QAction* accionAcercaDe;QAction* accionSalir ;QLabel* widgetCentral;

};#endif 

En la línea 4 incluimos el archivo de cabecera QMainWindow el cual contiene la definiciónde la clase en la que basaremos nuestra ventana principal.

En la línea 11 definimos nuestra clase VentanaPrincipal e indicamos que heredará deQMainWindow.

De la líneas 18 a 22 declaramos los slots por medio de los cuales implementaremos lafuncionalidad de nuestra aplicación.

Y finalmente de las líneas 24 a 32 declaramos las variables que utilizaremos en laaplicación.

ventanaprincipal.cpp

123456 7 891011121314

1516 17 181920212223

#include "ventanaprincipal.h" #include <QMenuBar> #include <QToolBar> #include <QLabel> #include <QStatusBar> #include <QMessageBox>  VentanaPrincipal::VentanaPrincipal(){

menuArchivo = menuBar ()-> addMenu(trUtf8("&Archivo"));menuAyuda = menuBar ()-> addMenu(trUtf8("A&yuda"));

 barraDeHerramientas = addToolBar (trUtf8("&Archivo"));

 widgetCentral =  new QLabel(trUtf8("Widget central"));widgetCentral-> setFont(QFont("Sans-Serif", 25));

 accionNuevo =  new QAction(QIcon("iconos/nuevo.png"),

trUtf8("&Nuevo"), this);accionNuevo-> setShortcut(QKeySequence::New );accionNuevo-> setStatusTip(trUtf8("Crear un nuevo archivo"));

 

8/4/2019 46172282 Tutorial de Qt

http://slidepdf.com/reader/full/46172282-tutorial-de-qt 31/47

242526 27 282930313233343536 37 383940414243

444546 47 484950515253545556 57 585960616263646566 67 686970

717273747576 77 787980

accionAbrir =  new QAction(QIcon("iconos/abrir.png"),trUtf8("&Abrir"), this);

accionAbrir -> setShortcut(QKeySequence::Open);accionAbrir -> setStatusTip(trUtf8("Abrir un archivo existente"));

 accionSalir =  new QAction(QIcon("iconos/salir.png"),

trUtf8("&Salir"), this);accionSalir -> setShortcut(QKeySequence::Quit);accionSalir -> setStatusTip(trUtf8("Salir de la aplicación"));

 accionAcercaDe =  new QAction(QIcon("iconos/salir.png"),

trUtf8("&Acerca de"), this);accionAcercaDe-> setShortcut(QKeySequence("Ctrl+d"));accionAcercaDe-> setStatusTip(trUtf8("Información sobre esta

aplicación")); 

menuArchivo-> addAction(accionNuevo);menuArchivo-> addAction(accionAbrir );menuArchivo-> addSeparator ();menuArchivo-> addAction(accionSalir );

 menuAyuda-> addAction(accionAcercaDe);

 barraDeHerramientas-> addAction(accionNuevo);barraDeHerramientas-> addAction(accionAbrir );barraDeHerramientas-> addSeparator ();barraDeHerramientas-> addAction(accionSalir );

 setCentralWidget(widgetCentral);statusBar ()-> showMessage(trUtf8("Bienvenido"));setWindowTitle("Ventana Principal");setMinimumSize(200, 200);

 connect(accionNuevo, SIGNAL(triggered ()),

  this, SLOT (accionNuevoLanzada())); 

connect(accionAbrir, SIGNAL(triggered ()),  this, SLOT (accionAbrirLanzada())); 

connect(accionAcercaDe, SIGNAL(triggered ()),  this, SLOT (accionAcercaDeLanzada())); 

connect(accionSalir, SIGNAL(triggered ()),  this, SLOT (accionSalirLanzada()));} void VentanaPrincipal::accionNuevoLanzada()

{widgetCentral-> setText(trUtf8("Acción \"Nuevo\" lanzada"));this-> resize(QSize(widgetCentral-> sizeHint().width(), 200));

} void VentanaPrincipal::accionAbrirLanzada(){

widgetCentral-> setText(trUtf8("Acción \"Abrir \" lanzada"));this-> resize(QSize(widgetCentral-> sizeHint().width(), 200));

}

8/4/2019 46172282 Tutorial de Qt

http://slidepdf.com/reader/full/46172282-tutorial-de-qt 32/47

8182838485

 void VentanaPrincipal::accionAcercaDeLanzada(){

QMessageBox ::about(this, this-> windowTitle(), trUtf8("Aquí se debecolocar información sobre la aplicación y la compañia que ladesarolla\n\n Tutoriales, artículos y enlaces de programaciónen:\n http://www.programacion-linux.com"));} void VentanaPrincipal::accionSalirLanzada(){  exit(0);}

De las líneas 1 a 7 incluimos los archivos de cabecera necesarios para implementar laaplicación.

En las línea 11 inicializamos la variable menuArchivo la cual representa un menú que podemos incluir en la barra de menús de la QMainWindow, para lograrlo utilizamos lasfunciones

QMenuBar * QMainWindow ::menuBar ()

Devuelve una referencia a una barra de menús que es creada al llamar a la función por  primera vez.

QMenu* QMenuBar ::addMenu(QString &texto)

Devuelve una referencia a un menú que se creará al llamar a la función y que mostrará en pantalla el texto indicado en la cadena de caracteres que se pasa como parámetro. En lalínea 12 realizamos lo mismo para el menú Ayuda.

En la línea 14 inicializamos la variable que representa a una barra de herramientas. Lafunción utilizada es:

QToolBar * QMainWindow ::addToolBar (QString &texto);

y trabaja de manera muy similar a las descritas anteriormente, es decir, devuelve unareferencia a una QToolBara que se crea cuando se llama a la función y que mostrará en pantalla la cadena que se pasa como parámetro.

En la línea 16 inicializamos la etiqueta que será utilizada como widget central en laaplicación. Y en la línea 17 establecemos la fuente que queremos que ocupe la etiqueta,esto se hace mediante la instrucción:

QLabel::setFont(QFont(QString &fuente, int tamanio));

La cual recibe como parámetros un objeto QFont, el cual representa una fuente de texto yque a su vez recibe como parámetros el nombre de la fuente y el tamaño de la misma.

En la línea 19 inicializamos nuestra variable accionNuevo, del tipo QAction, mediante elconstructor de la clase

QAction::QAction(QIcon(QString &archivo), QString &texto, QWidget* padre)

Este constructor recibe como parámetros un objeto QIcon, el cual representa un icono quese mostrará cuando la acción sea colocada dentro de una barra de herramientas y que a suvez recibe como parámetro una cadena de texto con la dirección dónde se encuentra elarchivo de imágen que mostrará el icono, el segundo parámetro del constructor de la clase

8/4/2019 46172282 Tutorial de Qt

http://slidepdf.com/reader/full/46172282-tutorial-de-qt 33/47

QAction es una cadena que indica el texto que se mostrará cuando la acción sea colocadadentro de una barra de menús y el último parámetro es el widget padre de la acción.

Antes de seguir debemos definir el concepto de QAction: Una QAction es unarepresentación abstracta de un comando de la aplicación que puede ser ejecutado por elusuario.

En muchas aplicaciones los mismos comandos, acciones o funciones pueden ser ejecutadosde diferentes maneras, ya sea mediante un elemento de la barra de menús, un icono dealguna barra de herramientas o una combinación de teclas, por mencionar algunosejemplos. Una QAction nos es muy útil en este tipo de situación ya que puede estar asociada a múltiples widgets, gracias a esto será posible proporcionar la misma función endistintos lugares de la aplicación y de manera sincronizada, entonces podemos decir queuna QAction proporciona una interfaz común para la ejecución de los comandos de laaplicación.

Siguiendo con el código, en la línea 20 establecemos un atajo de teclado para nuestraacción Nuevo, mediante la función

QAction::setShortcut(const QKeySecuence secuencia)

la cual recibe como parámetro un elemento de la enumeración QKeySecuence, dichaenumeración nos proporciona combinaciones estándar de teclas dependiendo de laconfiguración del sistema operativo en el que nos encontremos. Por ejemplo en el caso demi sistemas operativo el elemento QKeySecuence::New esta relacionado con lacombinación de teclas Ctrl+N sin embargo esto puede ser distinto en otro sistemaoperativo, pero al utilizar esta enumeración Qt se encargará de administrarlo y en caso deque se requiera, asociarlo a otra combinación de teclas más adecuada en esa situación.

En la línea 21 establecemos el texto que deseamos que se muestre en la barra de estatus al posicionar el cursor del mouse sobre los widgets relacionados con la accióncorrespondiente. Esto se logra mediante la función:

QAction::setStatusTip(QString &texto)La cual recibe como parámetro una cadena con el texto que deseamos mostrar.

En las líneas 23 a 33 realizamos lo mismo para las acciones restantes.

En las líneas 35 a 38 agregamos tres de las acciones que creamos al menú Archivo. Esto lohacemos a través de la función

QMenu::addAction(QAction* accion)

Con el fin de lograr un diseñod e interfaz de usuario más claro y atractivo en la línea 37agregamos un separardor, utilizando la función

QMenu::addSeparator ()

Un separador es una línea vertical u horizontal que separa las acciones que está colocadasdentro del mismo menú o barra de herramientas pero que pueden ser ubicadas en unacategoría específica o diferente del resto de las acciones del mismo menú o barra deherramientas.

En la línea 40 agregamos la acción AcercaDe al menú Ayuda.

En las líneas 42 a 45 agregamos las acciones a la barra de herramientas de la aplicaciónutilizando las mismas funciones que utilizamos para agregarlas a los menús.

En la línea 48 creamos la barra de estatus mediante la función

8/4/2019 46172282 Tutorial de Qt

http://slidepdf.com/reader/full/46172282-tutorial-de-qt 34/47

QMainWindow ::statusBar ()

La cual funciona de manera muy similar a las funciones utilizadas para crear las otras barras de la ventana principal, es decir, creará una barra de estatus para la ventana la primera vez que es llamada.

En la misma línea utilizamos la función

QStatusBar ::showMessage(QString &mensaje)

 para mostrar un mensaje en la barra de estatus, en este caso mostramos la palabra “Listo”con el fin de indicar que la aplicación puede comenzar a utilizarse.

En las líneas 52 y 53 conectamos la acción accionNuevo con su slot correspondiente, estolo realizamos mediante la función connect(), la cual revisamos a detalle en un artículoanterior. Debido a que una acción puede estar asociada a múltiples widgets no siempre serálanzada de la misma forma, debido a ello Qt nos proporciona la señal triggered() (lanzada odisparada) la cual se emitirá cada vez que un widget asociado a la señal sea activado, por ejemplo un clic sobre un botón lanzará una acción asociada al mismo mientras que unacombinación de teclas lanzará dicha acción al ser presionada por el usuario.

En las líneas 55 a 62 conectamos las acciones restantes a sus respectivos slots.En la línea 65 comienza la implementación de los slots, los slots accionNuevoLanzada yaccionAbriLanzada cambiarán el texto que se muestra en la etiqueta utilizada como widgetcentral y redimensionarán la ventana para ajustarla al nuevo texto mostrado. El cambio detexto de la etiqueta se realiza mediante la función

QLabel::setText(QString &texto)

la cual recibe como parámetro una cadena de caracteres con el texto que se desea mostrar.

El cambio de tamaño de la ventana se realiza mediante la función

QMainWindow ::resize(QSize(int width, int height))

esta función recibe como parámetro un objeto QSize, el cual es una estructura que incluye

el ancho y alto de un widget y que a su vez recibe como parámetros dos enteros indicandoel ancho y alto del widget, respectivamente.

También utilizamos la función sizeHint() la cual devuelve un objeto QSize con el tamañorequerido por el widget sobre el que se llamo la función.

En la línea 77 comienza la implementación del slot asociado a la acción acercaDe, en lalínea 79 indicamos que al dispararse dicha acción se mostrará el conocido diálogo acerca deel cuál contiene información sobre la aplicación como versióno fecha de lanzamiento ysobre la compañia que creo la aplicación.

Finalmente en las líneas 82 a 85 implementamos el slot asociado a la acción salir, en lalínea 84 utilizamos la función exit(int codigo) para indicar que deseamos salir de la

aplicación, la aplicación devolverá un código el código de error indicado como parámetro. Normalmente un valor de cero indica que la aplicación termino normalmente, es decir, sinningún error.

main.cpp

1234

#include "ventanaprincipal.h"#include <QApplication>  int main(int argc, char * argv [])

8/4/2019 46172282 Tutorial de Qt

http://slidepdf.com/reader/full/46172282-tutorial-de-qt 35/47

56 7 8910111213

{QApplication app(argc, argv );

 VentanaPrincipal* ventanaPrincipal =  new VentanaPrincipal;

 ventanaPrincipal-> show ();

 return app.exec();

}

En la línea 1 incluimos el archivo de cabecera de la clase VentanaPrincipal, mientras que enla línea 8 creamos e inicializamos un objeto de dicha clase, y finalmente en la línea 10mostramos nuestra ventana principal.

Al ejecutar esta aplicación de ejemplo obtendremos algo parecido a lo mostrado en lassiguientes imagenes:

8/4/2019 46172282 Tutorial de Qt

http://slidepdf.com/reader/full/46172282-tutorial-de-qt 36/47

Es todo en este artículo, en la siguiente parte del tutorial veremos como implementar unwidget personalizado, el cual podremos utilizar en futuras aplicaciones que desarrollemos.

Tutorial de Qt 4: Layouts, organización de los Widgets

En el ejemplo anterior realizamos nuestra primera aplicación en Qt, el clásico Hola Mundo,en el cual solamente creamos una etiqueta con el texto “Hola Mundo!” y la mostramos en pantalla. Utilizamos este enfoque debido a que realizamos un programa que sólo serviría deejemplo, pero en él se pueden apreciar serias deficiencias, tal vez la más notoria es que sóloes posible utilizar un elemento de interfaz gráfica (widget) a la vez, el cual en nuestro casofue una etiqueta.

En este artículo veremos la forma de solucionar esto: utilizando Layouts.

Los Layouts son objetos que nos permiten organizar los widgets dentro de una ventana, enQt disponemos de los siguientes tipos básicos de Layouts:

• QHBoxLayout

QVBoxLayout• QGridLayout

• QFormLayout

A continuación describiremos brevemente estos layouts y mostraremos un ejemplo básicode su uso.

QHBoxLayout

 Nos permite ordenar los widgets en filas, es decir, de manera horizontal.

8/4/2019 46172282 Tutorial de Qt

http://slidepdf.com/reader/full/46172282-tutorial-de-qt 37/47

El código para crear una aplicación con un layout como el de la imagen anterior es elsiguiente, explicaremos sólo las líneas de código que no hayan sido vistas a detalle en partes anteriores del tutorial:

123456 7 

8910111213141516 17 181920

212223242526 

#include <QObject> #include <QApplication> #include <QDialog> #include <QHBoxLayout> #include <QPushButton>  int main(int argc, char  *argv [])

{QApplication app(argc, argv );

 QDialog *ventana =  new QDialog ();QHBoxLayout *layout =  new QHBoxLayout();QPushButton *boton1 =  new QPushButton(QObject::trUtf8("Botón 1"));QPushButton *boton2 =  new QPushButton(QObject::trUtf8("Botón 2"));QPushButton *boton3 =  new QPushButton(QObject::trUtf8("Botón 3"));

 layout-> addWidget(boton1);layout-> addWidget(boton2);layout-> addWidget(boton3);

 

ventana-> setLayout(layout);ventana-> setWindowTitle("QHBoxLayout");ventana-> show ();

 return app.exec();

}

Las líneas 1 a 5 importan las bibliotecas necesarias para esta aplicación, QObject nos proveerá de la función trUtf8() necesaria para escribir cadenas con caracteres Unicode, ennuestro caso, caracteres propios del español como la ñ, o el acento (tilde).

QDialog es una clase que representa un diálogo de aplicación. Utilizamos un diálogo enlugar de una ventana principal buscando mantener la simplicidad del ejemplo. Un diálogoes una ventana mediante la cual el usuario y la aplicación se comunican. Algunos de sus

usos son:

• Informar al usuario sobre la ocurrencia de algún evento relevante comouna notificación al terminar un proceso o un error al realizarlo.

• Solicitar confirmación para realizar alguna acción como borrar o guardarun archivo.

• Solicitar información, como la palabra a buscar en un diálogo de buscary reemplazar.

8/4/2019 46172282 Tutorial de Qt

http://slidepdf.com/reader/full/46172282-tutorial-de-qt 38/47

QHBoxLayout es una clase que representa a nuestro layout horizontal. QPushButton es unaclase que representa a un botón estándar.

111213

QDialog *ventana =  new QDialog ();QHBoxLayout *layout =  new QHBoxLayout();QPushButton *boton1 =  new QPushButton(QObject::trUtf8("Botón 1"));

En las líneas 11 a 13 creamos un nuevo diálogo, layout y botón mediante la sentencia new para ejecutar el constructor de cada clase, en este caso el constructor del botón es el únicoque recibe parámetros, este parámetro es una cadena de texto que contenga la etiqueta quedebe mostrar el botón. Las líneas 14 y 15 crean los otros botones de la misma forma.

17 1819

layout-> addWidget(boton1);layout-> addWidget(boton2);layout-> addWidget(boton3);

En las líneas 17 a 19 colocamos los botones dentro de nuestro layout mediante la función

addWidget(QWidget *widget, int stretch= 0, Qt::Alignment aling = 0)

Esta función recibe como parámetros un apuntador al widget que deseamos agregar, unentero que indica el indice de “flexibilidad” (stretch) del widget y un elemento de laenumeración Qt::Alignment, los últimos dos parámetros pueden omitirse y en caso dehacerlo se les asiga el valor de cero. El stretch indica la proporción de espacio disponible enel layout que el widget ocupará, es relativo al stretch indicado en los otros widgets queestán dentro del layout, entre mayor sea el valor de stretch mayor será el espacio queocupará el widget. La enumeración Qt:Alignment indica la alineación que tendrá el widgety puede tener los siguiente valores:

• Horizontales: Qt::AlignLeft (izquierda), Qt::AlignRight (derecha),Qt::AlignHCenter (centrado horizontalmente), Qt::AlignJustify (justificado)

• Verticales:Qt::AlignTop (superior/arriba), Qt::AlignBottom(inferior/abajo), Qt::AlignVCenter (centrado verticalmente)

Bidimensionales:Qt::AlignCenter (centrado horizontal y verticalmente)Los widgets se colocan en el orden en que se ejecutan las instrucciones, de forma que eneste layout el primer botón de izquierda a derecha (la dirección por default de este layout)es boton1 seguido de boton2 y por último boton3. Si queremos invertir el orden de loswidgets podemos escribir las instrucciones en orden inverso o podemos indicar quenuestros widgets se añadan de derecha a izquierda con la instrucción

setDirection(QBoxLayout:RightToLeft)

17 18

ventana-> setLayout(layout);ventana-> setWindowTitle("QHBoxLayout");

En la línea 17 establecemos nuestro layout como el principal de la ventana, es decir el queindicará como se muestran los widgets en esa ventana. Y por último en la línea 18

indicamos el título que queremos que muestre nuestra ventana, si no se especifica seutilizará el del nombre del archivo.

QVBoxLayout

 Nos permite ordenar los widgets en columnas, es decir, de manera vertical.

8/4/2019 46172282 Tutorial de Qt

http://slidepdf.com/reader/full/46172282-tutorial-de-qt 39/47

El código para crear una aplicación con un layout como el de la imagen anterior es elsiguiente:

123456 

7 8910111213141516 17 1819

20212223242526 

#include <QObject> #include <QApplication> #include <QDialog> #include <QVBoxLayout> #include <QPushButton>  

int main(int argc, char  *argv []){

QApplication app(argc, argv ); 

QDialog *ventana =  new QDialog ();QVBoxLayout *layout =  new QVBoxLayout();QPushButton *boton1 =  new QPushButton(QObject::trUtf8("Botón 1"));QPushButton *boton2 =  new QPushButton(QObject::trUtf8("Botón 2"));QPushButton *boton3 =  new QPushButton(QObject::trUtf8("Botón 3"));

 layout-> addWidget(boton1);layout-> addWidget(boton2);layout-> addWidget(boton3);

  ventana-> setLayout(layout);ventana-> setWindowTitle("QVBoxLayout");ventana-> show ();

 return app.exec();

}

Si lo comparamos con el ejemplo anterior del QHBoxLayout, lo único que cambia es quenuestro objeto layout ahora es de tipo QVBoxLayout, el resultado de esto es que loswidgets ahora se organizan de acuerdo a las reglas de este layout, es decir, de arriba haciaabajo. Si queremos invertir el orden en que se agregan los widgets al layout utilizamos lainstrucción

setDirection(QBoxLayout::BottomToTop);

QGridLayout

 Nos permite ordenar los widgets a manera de tabla o rejilla.

8/4/2019 46172282 Tutorial de Qt

http://slidepdf.com/reader/full/46172282-tutorial-de-qt 40/47

El código para crear una aplicación con un layout similar al de la imagen es:

123456 7 8910

111213141516 17 18192021222324

2526 

#include <QObject> #include <QApplication> #include <QDialog> #include <QGridLayout> #include <QPushButton>  int main(int argc, char  *argv []){

QApplication app(argc, argv ); 

QDialog *ventana =  new QDialog ();QGridLayout *layout =  new QGridLayout();QPushButton *boton1 =  new QPushButton(QObject::trUtf8("Botón 1"));QPushButton *boton2 =  new QPushButton(QObject::trUtf8("Botón 2"));QPushButton *boton3 =  new QPushButton(QObject::trUtf8("Botón 3"));

 layout-> addWidget(boton1, 0, 0);layout-> addWidget(boton2, 0, 1);layout-> addWidget(boton3, 1, 0);

 ventana-> setLayout(layout);ventana-> setWindowTitle("QGridLayout");ventana-> show ();

 

return app.exec();}

 Nuevamente cambiamos el tipo de nuestro objeto layout, ahora será de la claseQGridLayout.

La forma de agregar los widgets a este tipo de layout es ligeramente distinta, ahora loharemos mediante la función

addWidget(QWidget *widget, int fila, int columna, Qt::Alignment align= 0);

Esta función recibe como parámetros un apuntador al widget que deseamos agregar, dosenteros que indican la fila y columna, respectivamente, de la celda sobre la cual queremosagregar el widget en cuestión y un valor de la enumeración Qt::Alignment. Las filas y

columnas comienzan a contarse desde cero de tal manera que la primera celda en la esquinasuperior izquierda tiene la posición fila=0, columna=0.

17 1819

layout-> addWidget(boton1, 0, 0);layout-> addWidget(boton2, 0, 1);layout-> addWidget(boton3, 1, 0);

En la línea 17 colocamos al primer botón en la celda definida por la intersección de la filacero con la columna cero, es decir, posición 0,0. Luego colocamos al boton2 y boton3 enlas celdas 0,1 y 1,0 respectivamente.

8/4/2019 46172282 Tutorial de Qt

http://slidepdf.com/reader/full/46172282-tutorial-de-qt 41/47

El espacio vacío en la celda 1,1 se genera debido a que el QGridLayout crea tantasdivisiones de filas y columnas como el número máximo de filas o columnas queindiquemos, en este caso dos, debido a la existencia de las filas y columnas uno y cero. Por ejemplo, si añadieramos los botones al layout mediante las líneas

  layout-> addWidget(boton1, 0, 0);layout-> addWidget(boton2, 1, 1);layout-> addWidget(boton3, 2, 2);

Obtendríamos el siguiente resultado:

Sin embargo habrá que tener en cuenta que las filas o columnas extras no serán visibles amenos que establezcamos el alto/ancho mínimo de cada fila/columna o que coloquemos unwidget en la fila/columna correspondiente, en este último caso (que es lo que ha ocurrido enlos dos ejemplos anteriores) el QGridLayout asigna automáticamente el alto/ancho mínimode esta fila/columna con un valor igual al mínimo requerido por el widget en cuestión.Podemos establecer el ancho mínimo de una columna y el alto mínimo de una fila con lasfunciones:

setColumnMinimumWidth(int columna, int anchoMinimo )setRowMinimumHeight(int fila, int altoMinimo)

Por ejemplo si añadieramos los botones al layout mediante el siguiente código:layout-> addWidget(boton1, 0, 0);layout-> addWidget(boton2, 1, 1);layout-> addWidget(boton3, 3, 3);

Se crearían cuatro filas y cuatro columnas, es decir, una fila y columna más que en elejemplo anterior, pero al ejecutar el programa obtendríamos el mismo resultado que semuestra en la imagen pasada. Esto ocurre debido a que aunque la fila y columna con elnúmero dos existen, estas tienen un alto y ancho de cero ya que no hemos colocado ningúnwidget en ellas ni hemos establecido el tamaño mínimo para ellas. Pero si después de lalínea dónde agregamos el último botón al layout añadimos las líneas:

layout-> setColumnMinimumWidth(2, 60);layout-> setRowMinimumHeight(2, 20);

Obtendríamos el siguiente resultado:

8/4/2019 46172282 Tutorial de Qt

http://slidepdf.com/reader/full/46172282-tutorial-de-qt 42/47

QFormLayout

 Nos permite ordenar los widgets de manera similar a la de formulario web, es decir, filascompuestas por un par de widgets, los cuales normalmente son una etiqueta y un campo detexto.

El código para crear una aplicación con un layout como el de la imagen anterior es elsiguiente:

12345

6 7 8910111213141516 17 181920212223242526 

#include <QObject> #include <QApplication> #include <QDialog> #include <QFormLayout> #include <QPushButton> 

 int main(int argc, char  *argv []){

QApplication app(argc, argv ); 

QDialog *ventana =  new QDialog ();QVBoxLayout *layout =  new QVBoxLayout();QPushButton *boton1 =  new QPushButton(QObject::trUtf8("Botón 1"));QPushButton *boton2 =  new QPushButton(QObject::trUtf8("Botón 2"));QPushButton *boton3 =  new QPushButton(QObject::trUtf8("Botón 3"));

 layout-> addRow (QObject::trUtf8("Botón 1:"), boton1);layout-> addRow (QObject::trUtf8("Botón 2:"), boton2);layout-> addRow (QObject::trUtf8("Botón 3:"), boton3);

 ventana-> setLayout(layout);ventana-> setWindowTitle("QVBoxLayout");ventana-> show ();

 return app.exec();

}

8/4/2019 46172282 Tutorial de Qt

http://slidepdf.com/reader/full/46172282-tutorial-de-qt 43/47

En este caso nuestro layout será del tipo QFormLayout y para añadir widgets utilizarermosla función

addRow (QLabel *etiqueta, QWidget *widget);

aunque también es posible utilizar la siguiente función sobre cargada, con el fin de evitar crear una etiqueta para cada uno de los widgets que deseeemos agregar:

addRow(const QString &amp;texto, QWidget *widget)

17 1819

layout-> addRow (QObject::trUtf8("Botón 1:"), boton1);layout-> addRow (QObject::trUtf8("Botón 2:"), boton2);layout-> addRow (QObject::trUtf8("Botón 3:"), boton3);

En las líneas 17 a 19 agregamos los widgets al layout, utilizamos la versión sobrecargadade addRow() en la que el primer parámetro es una cadena de texto con el fin de ahorrar código, debido a que en este ejemplo no necesitamos que el texto de alguna fila cambie y por lo tanto no es necesario conservar un apuntador hacia las etiquetas. Este tipo de layoutes muy útil, por ejemplo, en la creación de formularios para la solicitud de información(como un registro de usuarios o un formulario de comentarios) en dónde debemos deindicar que información debe de capturar el usuario en cada campo.

Layouts Anidados

 Normalmente las aplicaciones que desarrollemos no tendrán una interfaz tan sencilla como para ser diseñadas utilizando sólo un layout, para organizar los widgets de maneras máscomplejas utilizamos layouts anidados, es decir, un layout dentro de otro. La función quenos permite anidar layouts depende del tipo de layout que estemos utilizando, paraQHBoxLayout y QVBoxLayout la función es:

addLayout(QLayout *layout, int Qt::Alignment align= 0)

Para el QGridLayout además debemos especificar la fila y columna de la celda dóndedeseamos agregar el layout, de la siguiente forma

addLayout(QLayout *layout, int fila, int columna, Qt::Alignment align= 0)

Para el QFormLayout se utiliza una función sobrecargada de addRow(), en una de lassiguientes formas, dependiendo de la apariencia que deseemos lograr:

addRow (QLabel *label, QLayout *layout)addRow (QString &amp;texto, QLayout *layout)

Está función recibe como parámetros un apuntador a la etiqueta que contiene el texto quedescribe al layout o simplemente una QString con ese texto y un apuntador al layout quedeseamos agregar.

addRow (QLayout *layout)

Esta función recibe cómo parámetro un apuntador al layout que deseamos agregar.

A continuación mostraremos un sencillo ejemplo de anidación de layouts para crear una

interfaz de usuario muy conocida: un formulario de inicio de sesión.

8/4/2019 46172282 Tutorial de Qt

http://slidepdf.com/reader/full/46172282-tutorial-de-qt 44/47

123456 7 8910111213141516 17 181920

212223242526 27 282930313233343536 37 383940414243444546 47 

48

#include <QApplication> #include <QHBoxLayout> #include <QVBoxLayout> #include <QLabel> #include <QLineEdit> #include <QPushButton> #include <QDialog>  int main(int argc, char  *argv []){QApplication app(argc, argv ); QDialog *ventana =  new QDialog ();QHBoxLayout *layoutUsuario =  new QHBoxLayout();QHBoxLayout *layoutContrasenia =  new QHBoxLayout();QHBoxLayout *layoutBotones =  new QHBoxLayout();QVBoxLayout *layoutPrincipal =  new QVBoxLayout(); QLabel *etiquetaUsuario =  new QLabel("Usuario");QLabel *etiquetaContrasenia =  new QLabel("Password");

 QLineEdit *campoUsuario =  new QLineEdit();QLineEdit *campoContrasenia =  new QLineEdit(); QPushButton *botonAceptar =  new QPushButton("Aceptar");QPushButton *botonCancelar =  new QPushButton("Cancelar"); layoutUsuario-> addWidget(etiquetaUsuario);layoutUsuario-> addWidget(campoUsuario); layoutContrasenia-> addWidget(etiquetaContrasenia);layoutContrasenia-> addWidget(campoContrasenia); layoutBotones-> addStretch();layoutBotones-> addWidget(botonAceptar );layoutBotones-> addWidget(botonCancelar ); layoutPrincipal-> addLayout(layoutUsuario);layoutPrincipal-> addLayout(layoutContrasenia);layoutPrincipal-> addLayout(layoutBotones); ventana-> setLayout(layoutPrincipal); ventana-> setWindowTitle(QObject::trUtf8("Iniciar Sesión"));ventana-> show (); return app.exec();

}

Al ejecutar este código obtendremos una salida parecida a la siguiente imagen

8/4/2019 46172282 Tutorial de Qt

http://slidepdf.com/reader/full/46172282-tutorial-de-qt 45/47

En las líneas 1 a 7 incluimos los archivos de cabecera necesarios para desarrollar laaplicación, mientras que en las líneas 13 a 26 creamos los widgets que utilizaremos. En laslíneas 28 y 29 colocamos los widgets del campo usuario en un QHBoxLayout, lo mismohacemos para los campos de contraseña y para los botones. Con el fin de lograr una interfazmás agradable alineamos los botones a la derecha insertando un espacio en blanco al principio del QHBoxLayout mediante la instrucción

addStretch(int stretch=0);

38

39404142

layoutPrincipal-> addLayout(layoutUsuario);

layoutPrincipal-> addLayout(layoutContrasenia);layoutPrincipal-> addLayout(layoutBotones); ventana-> setLayout(layoutPrincipal);

A partir de la línea 38 agregamos en el layout principal (el cual es un QVBoxLayout) ellayout que contiene los controles de usuario, seguido por el que contiene los controles decontraseña y por último el que contiene los botones y finalmente en la línea 40establecemos el layout principal de nuestra apliciación.

Es posible diseñar una interfaz de usuario utilizando distintas combinaciones de layouts, escuestión de tiempo y experiencia poder encontrar aquella que sea más fácil y rápida decrear o la que se adapte mejor a las necesidades de nuestra aplicación. Para el ejemplo

anterior un mejor diseño (considerando que requiere menos líneas) puede lograrseutilizando un QFormLayout en lugar de los primeros dos QHBoxLayout. El código es elsiguiente:

123456 7 8910

111213141516 17 181920

#include <QApplication> #include <QHBoxLayout> #include <QFormLayout> #include <QLineEdit> #include <QPushButton> #include <QDialog>  int main(int argc, char  *argv []){QApplication app(argc, argv );

 QDialog *ventana =  new QDialog ();QHBoxLayout *layoutBotones =  new QHBoxLayout();QFormLayout *layoutPrincipal =  new QFormLayout(); QLineEdit *campoUsuario =  new QLineEdit();QLineEdit *campoContrasenia =  new QLineEdit(); QPushButton *botonAceptar =  new QPushButton("Aceptar");QPushButton *botonCancelar =  new QPushButton("Cancelar");

8/4/2019 46172282 Tutorial de Qt

http://slidepdf.com/reader/full/46172282-tutorial-de-qt 46/47

212223242526 27 282930313233343536 37 

 layoutBotones-> addStretch();layoutBotones-> addWidget(botonAceptar );layoutBotones-> addWidget(botonCancelar ); layoutPrincipal-> addRow (QString ("Usuario"), campoUsuario);layoutPrincipal-> addRow (QString ("Password"), campoContrasenia);layoutPrincipal-> addRow (layoutBotones); ventana-> setLayout(layoutPrincipal); ventana-> setWindowTitle(QObject::trUtf8("Iniciar Sesión"));ventana-> setWindowFlags(Qt::Window );ventana-> show (); return app.exec();}

Al ejecutar este código obtenemos una salida similar a la siguiente

La cual tiene una apariencia muy similar a la del ejemplo anterior y que en mi opiniónincluso se ve mejor, pero lo importante es que el número de líneas utilizadas se redujo un poco, pero es de suponer que en una aplicación de mayor tamaño el ahorro de líneas decódigo también será mayor.

Tutorial Gtk+ 2: Instalacion de Gtk+ 2 en Linux

Gtk+ es, de manera parecida a Qt, un conjunto de herramientas usado para crear interfazgráfica de usuario, escrito completamente en C, no se encuentra orientado a objetos, sinembargo “simula” estarlo, al estar programado en C es bastante flexible con otroslenguajes y facilmente adaptable, la interfaz grafica de Gnome (el entorno de escritorio deUbuntu) esta creada con Gtk+.

Instalacion de Gtk con Gestor de paquetes.Instalar Gtk con un gestor de paquetes como es el Synaptic de Ubuntu es bastante sencilloya que solamente necesitamos localizar la libreria con el nombre de “libgtk2.0-dev” y

nuestro magico gestor de paquetes resolvera las dependencias de librerias necesarias paraque todo funcione correctamente.

Instalacion de Gtk+ con paquetes de distribución (O la ruta escénica)

El primer paso es conseguir el paquete de distribución de la página www.gtk.org de lasección de descargas de la misma, el segundo es extraerlo a la carpeta donde tendremostodos nuestros archivos de origen, esto lo hacemos con los comandos:

tar xvfz gtk+-2.0.0.tar.gztar xvfj gtk+-2.0.0.tar.bz2

8/4/2019 46172282 Tutorial de Qt

http://slidepdf.com/reader/full/46172282-tutorial-de-qt 47/47

Despues de hacer esto nos ubicamos en la carpeta donde se contienen todos los demasarchivos y ejecutamos el script llamado configure el cual crea archivos makefileadecuados al sistema operativo, la manera mas comun de hacer esto es:

./configure --prefix=/opt/gtk

Despues de hacer esto simplemente hacemos uso de los archivos recien creados e

instalamos con los siguientes comandos:makemake install

Despues de esto puede que sea necesario hacerle saber al sistema operativo acerca de lasnuevas librerias dinámicas esto lo hacemos ejecutando:

ldconfig 

Una vez hecho esto al fin hemos conseguido instalar Gtk+ en uestra maquina con Linux, siocurrel agun fallo a pesar de que ya se encuentra instalado Gtk+, lo mas probable es que setrate de alguna libreria de la cual depende gtk para compilar/ejecutar, la manera mas fácilde comprobar que nuestro Gtk+ fue instalado con exito es ejecutar en nuestra liena de

comandos el demo que viene jutno con Gtk+:gtk-demo

Con esto tenemos todo listo para crear nuestro “Hola Mundo” en Gtk+.