Sei sulla pagina 1di 47

Tutorial de Qt - Captulo 1

Resumen
En nuestro primer programa mostraremos la tpica frase "Hola Mundo!". Solo contiene lo indispensable para poner en marcha una aplicacin Qt. La siguiente imagen es una captura de lo que vamos a hacer:

Veamos el cdigo completo de la aplicacin: #include <QApplication> #include <QPushButton> int main(int argc, char *argv[]) { QApplication app(argc, argv); QPushButton hello("Hola Mundo!"); hello.show(); return app.exec(); }

Explicacin
#include <QApplication>

Esta linea incluye la definicin de la clase QApplication. Solo tiene que haber un objeto QApplication en cada aplicacin con GUI que use Qt. QApplication maneja los diferentes recursos de la aplicacin, como la fuente por defecto y el cursor. #include <QPushButton>

Esta linea incluye la definicin de la clase QPushButton. Para cada clase de la API de Qt existe un fichero de cabecera con el mismo nombre que contiene su definicin. Un QPushButton es un botn 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 grficos 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[]) {

La funcin main() es el punto de entrada del programa. Casi siempre que usemos Qt, main() solo necesitar realizar algn tipo de inicializacin antes de pasar el control a la biblioteca Qt, la cual le comunicar al programa como actuar con el usuario a travs de los eventos que genere. El parmetro argc es el numero de argumentos pasados por la linea de ordenes, y argv es el array que contiene dichos argumentos. Esto es una definicin estndar 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 cdigo relacionado con la interfaz, hemos creado un botn. Establecemos que el botn muestre el texto "Hola Mundo!". Como no hemos especificado una ventana padre (por ejemplo mediante el segundo argumento del constructor de QPushButton), el botn ser una ventana en si misma, con su propio marco de venta y su barra de titulo. El tamao del botn est determinado por su propio tamao por defecto. Podramos llamar a QWidget::move() para asignarle una posicin determinada al widget, pero por ahora vamos a permitir que el administrador de ventanas elija su posicin. 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 aplicacin (QCoreApplication es la clase base de QApplication. Implementa el ncleo deQApplication, la funcionalidad no-GUI y puede usarse para desarrollar aplicaciones sin GUI).

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 aplicacin.


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 aplicacin Qt!.

Ejercicios.
Intenta redimensionar la ventana. Pulsa el botn. Intenta ejecutar el programa con la opcin -geometry (por ejemplo -geometry 100x200+10+20).

Resumen Este ejemplo es una continuacin de la ventana creada en el capitulo 1. Vamos a hacer que la aplicacin se cierre correctamente cuando el usuario se lo diga. Tambin vamos a usar un tipo de letra mas atractivo de la que se muestra por defecto.

Veamos el cdigo completo de la aplicacin: #include <QApplication> #include <QFont> #include <QPushButton> int main(int argc, char *argv[]) { QApplication app(argc, argv);

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(); } Explicacin #include <QFont> Como vamos a usar QFont en nuestro programa, tenemos que incluir QFont. QPushButton quit("Quit"); Esta vez el botn mostrara el texto Quit, y eso ser lo que el programa haga cuando lo pulsemos. quit.resize(75, 30); Hemos elegido otro tamao para el botn ya que el texto es algo mas corto que "Hola Mundo!". Tambin podramos haber usado QFontMetrics para establecer el tamao adecuado, o permitir que QPushButton eligiera un tamao razonable por defecto. quit.setFont(QFont("Times", 18, QFont::Bold)); Elegimos una nueva fuente para el botn: Times y negrita de 18 puntos. Tambin es posible cambiar la fuente por defecto de toda la aplicacin mediante QApplication::setFont(). QObject::connect(&quit, SIGNAL(clicked()), &app, SLOT(quit())); QObject::connect() es quizs la caracterstica mas importante de Qt. Ten en cuenta que connect() es una funcin esttica de QObject, no confundirla con la funcin connect() de la biblioteca de sockets de Berkeley. La llamada a connect() establece una conexin "en una sola direccin" entre dos objetos de Qt (objetos que heredan de QObject, directa o indirectamente). Cada objeto de Qt puede tener signals (para mandar mensajes) y slots (para recibir mensajes). Todos los widgets son objetos de Qt ya que heredan de QWidget, que a su vez hereda de QObject. En nuestro caso, la seal clicked() de quit se conecta al slot quit() de app, as cuando se pulsa el botn, se termina la ejecucin de la aplicacin. La documentacin de Signals and slots explica este mecanismo en profundidad. Compilar y ejecutar la aplicacin. Podemos compilar y ejecutar la aplicacin de forma similar al capitulo 1. Si pulsamos el botn Quit, vemos como la aplicacin termina su ejecucin.

Ejercicios. Intenta redimensionar la ventana. Pulsa el botn para cerrar la aplicacin. Existe alguna otra seal de de QPushButton que puedas conectar al botn? (sugerencia: QPushButton hereda la mayor parte de su funcionalidad de QAbstractButton). Resumen En el tercer captulo vamos a ver como crear widgets padres y widgets hijos de la forma mas 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(); } Explicacin #include <QWidget> Aadimos la cabecera de QWidget para poder usarla. QWidget window; Creamos simplemente un widget. La clase QWidget es la clase base de todos los objetos de la interfaz de usuario. Un widget es el tomo de la interfaz de usuario: captura el ratn, el teclado y otros eventos del administrador de ventanas, y dibuja una representacin de si

mismo en la pantalla. Un widget queda recortado por su widget padre y por widgets que estan delante de l. A un widget que no est relacionado con un widget padre, como el que hemos creado, se le llama ventana. Normalmente las ventanas tienen su propio marco de ventana y una entrada en la barra de tareas, proporcionado por el administrador de ventanas. Un widget sin widget padre siempre es una ventana independiente y su posicin 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 es recortado por los limites del padre. Por defecto se ancla a la esquina superior izquierda, en la posicin (0, 0). quit.setGeometry(10, 40, 180, 40); La funcion QWidget::setGeometry() tiene cuatro argumentos: los dos primeros son las coordenadas x e y de la esquina superior izquierda del botn (relativas al widget padre), y los dos ltimos son la anchura y la altura del botn. El resultado es un botn que ocupa desde la posicin (10, 40) hasta la posicin (190, 80). window.show(); Cuando mostramos un widget padre, este llamar a la funcin show() de cada uno de sus hijos (excepto aquellos que se ocultaron explicitamente mediante QWidget:hide()). Los lectores del tutorial que ya hayan estudiado la documentacin de QObject recordarn que cuando se invoca al destructor de un QObject, si el QObject tiene hijos, el destructor invocado llamar automticamente al destructor de cada hijo. Puede parece que el destructor del botn quit se invocar dos veces al final de main(), una cuando su padre (window) sale de su mbito y el destructor elimina el botn porque es hijo suyo, y otra cuando el botn sale de su mbito. No hay necesidad de preocuparse en este caso, ya que el cdigo es correcto. De todas formas, existe un caso en el que el programador debe ser consciente del orden de la destruccin de objetos en la pila (puedes ver la explicacin del orden de construccin/destruccin de QObjects aqui). Ejecutar la aplicacin. A diferencia del capitulo 2 del tutorial, el botn ya no llena toda la ventana, sino que se mantiene en la posicin (10, 40) dentro de la ventana con un tamao (180, 40), debido a la llamada a QWidget::setGeometry(). Ejercicios. Intenta redimensionar la ventana, Cmo cambia el botn? Qu sucede con la altura del botn si se ejecuta el programa con un tipo de letra mas grande?Qu ocurre si intentas hacer la ventana muy pequea?

Resumen En este captulo vamos a ver como crear nuestro propio widget y como controlar el tamao mnimo y mximo 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(); } Explicacin class MyWidget : public QWidget { public:

MyWidget(QWidget *parent = 0); }; Lo primero que hacemos es crear una nueva clase. Como hereda de QWdiget, la nueva clase podr ser un widget (y quiz una ventana independiente) o un widget hijo (como el QPushButton del captulo anterior). La clase solo tiene un miembro, el constructor (adems de los miembros heredados de QWdiget). El constructor es un constructor estndar de widget de Qt; deberas incluir siempre un constructor similar cuando crees un widget. El argumento del constructor es el widget padre. Para crear una ventana independiente con el widget debes especificar un puntero nulo como padre. Como puedes ver, el widget es por defecto una ventana independiente. MyWidget::MyWidget(QWidget *parent) La implementacin del constructor empieza aqu. Como la mayora 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 tamao. En el siguiente captulo veremos como un widget puede responder al redimensionado por parte del 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 es this, es decir, la instancia de MyWidget). La funcin tr() marca la cadena "Quit" para que pueda ser traducida, haciendo posible cambiarla en tiempo de ejecucin segn los archivos de traduccin. Es un buen habito usar tr() en todas las cadenas visibles al usuario en el caso de que decidas traducir mas tarde tu aplicacin a otros idiomas. Ten en cuenta de que quit es una variable local del constructor. MyWdiget no hace un seguimiento de ella; Qt es quien lo hace y la borrar automticamente cuando el objeto MyWdiget sea destruido (No hay nada malo en borrar un hijo cuando lo desees, el hijo avisar automticamente a Qt de su muerte inmediatamente). La llamada a QWidget::setGeometry() establece la posicin y el tamao 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, y apunta a la instancia nica de QApplication en la aplicacin. int main(int argc, char *argv[]) { QApplication app(argc, argv); MyWidget widget;

widget.show(); return app.exec(); } Instanciamos nuestro nuevo hijo, lo mostramos y ejecutamos la aplicacin. Ejecutar la aplicacin. El comportamiento del programa es muy similar al del captulo anterior, la diferencia reside en 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 aadir mas botones o a incluir otros widgets a parte de QPushButton. Resumen En el quinto captulo del tutorial vamos a ver como crear y conectar varios widgets entre ellos usando signals y slots, y como manejar el redimensionado de varios widgets en nuestra aplicacin.

#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);

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(); } Explicacin 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 nmero como si fuera un LCD. Vamos a hacer que lcd muestre dos dgitos y estableceremos la propiedad QLCDNumber::segmentStyle a QLCDNumber::Filled para que sea mas legible. QSlider *slider = new QSlider(Qt::Horizontal); slider->setRange(0, 99); slider->setValue(0);

El usuario puede usar un QSlider para ajustar un valor entero dentro de un rango. Con estas tres 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 seal valueChanged() del slider al slot display() del LCD. Cada vez que el valor del slide cambie, este emitir el nuevo valor lanzando la signal valueChanged(). Como esta seal est conectada al slot display() del LCD, se llamar al slot cuando la seal sea emitida. Ten en cuenta que ninguno de los objetos sabe sobre el otro (esencial en la programacin con componentes). Por otra parte, los slots son funciones miembro normales y siguen las reglas de acceso normal 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 geometra de sus widgets hijos. Por esta razn ya no necesitamos especificar las coordenadas en la pantalla para cada widget hijo tal como hicimos en el captulo 4. Adems, usar un layout asegura que se redimensionen los widgets hijos cuando la ventana se redimensione. Por tanto aadimos los widgets quit, lcd y slider al layout mediante QBoxLayout::addWidget(). La funcin QWidget::setLayout() establece el layout de MyWidget. Esto hace que el layout sea hijo de MyWidget, por lo que no tenemos que preocuparnos de borrarlo, la relacin padre-hijo asegura que ser borrado junto a MyWidget. Adems, la llamada QWidget::setLayout() ajusta automaticamente los widgets en el layout como hijos de MyWidget. 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 pueden no tener padre. Un widget se puede aadir a un layout, lo cual hace que el layout sea el responsable de manejar la geometra 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 aplicacin. El LCD de nmeros refleja los cambios hechos en el slider, y los widgets se redimensionan de forma correcta. Date cuenta de que el widget LCD cambia de tamao cuando se cambia el tamao de la ventana (porque puede), pero los otros siguen teniendo el mismo tamao (lo contrario sera sera extrao). Ejercicios. Intenta cambiar el LCD aadiendo mas dgitos o cambiando el modo (QLCDNumber::setMode()). Incluso puedes aadir cuatro botones para establecer la base del nmero (decimal, hexadecimal, octal o binaria).

Tambin 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 aplicacin se cierre si se produce un desbordamiento en el LCD. Otra Guia:

Tutorial de Qt 4: Nuestro primer programa, Hola Mundo


En este artculo vamos a crear y explicar a detalle la clsica primera aplicacin en programacin, esta vez con Qt. El cdigo de un Hola Mundo en Qt es el siguiente
1 #include <QApplication> 2 #include <QLabel> 3 4 int main(int argc, char *argv[]) 5 { 6 QApplication app(argc, argv); 7 QLabel *label = new QLabel("Hola Mundo!"); 8 9 label->show(); 10 11 return app.exec(); 12 } 1 #include <QApplication> 2 #include <QLabel>

Incluimos los archivos de cabecera que utilizaremos para el ejemplo, QApplication es una clase que representa una aplicacin grfica de Qt, es la encargada de administrar el flujo de ejecucin y la configuracin principal de la aplicacin. QLabel es una clase que representa a 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 funcin main en la cual comenzar la ejecucin de nuestro programa, es necesario especificar los argumentos de lnea de comandos argc (un entero que contiene el nmero de argumentos) y argv (un arreglo/matriz que contiene el valor de cada uno de los argumentos) ya que al crear un objeto de la clase QApplication es necesario especificarlos.
6 QApplication app(argc, argv);

Crea el objeto QApplication llamado app y pasa como parmetros los argumentos de lnea de comandos.
7 QLabel *label = new QLabel("Hola Mundo!");

Crea un apuntador a un objeto QLabel llamado label, y lo inicializa con la sentencia new QLabel(Hola Mundo!), la cual reserva memoria para la etiqueta que contendr el texto que 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();

Muestra la etiqueta en pantalla. Qt se encargar de crear una ventana para poder mostrar la etiqueta en pantalla ya que nosotros no hemos asignado alguna.
11 return app.exec();

Inicia el hilo principal de la aplicacin a partir de este momento el framework toma el control de la aplicacin y responde a la interaccin del usuario con los controles de interfaz grfica de acuerdo a todo lo especificado anteriormente. La sentencia return regresa al sistema operativo la respuesta de la ejecucin del programa una vez que ha finalizado, est respuesta tipicamente ser cero en caso de que la aplicacin se haya ejecutado exitosamente. Compilacin y Ejecucin Guardamos el archivo como holamundo.cpp o cualquier otro nombre con extensin .cpp. Abrimos una terminal en la ubicacin de nuestro archivo holamundo.cpp y ejecutamos los siguientes comandos.
qmake -project

Crea un archivo de proyecto para nuestra aplicacin


qmake holamundo.pro

Crea un archivo de proyecto especfico para la plataforma o SO en el que estamos trabajando


make

Generar un archivo ejecutable correspondiente a nuestra aplicacin.


./holamundo

Ejecuta el archivo ejecutable generado por el compilador al procesar nuestro cdigo. Si todo ha ido bien deberas ver una ventana parecida a la siguiente

Tutorial de Qt4: Dilogos, comunicacin con el usuario (Parte II)


En el artculo anterior revisamos la primera de las dos formas principales de utilizar dilogos en Qt, esto es creando clases que hereden de QDialog, implementando la funcionalidad de estas clases y gestionando las respuestas que recibimos a travs de la funcin QDialog::exec()

En este artculo veremos la segunda forma de utilizar dilogos en una aplicacin de Qt, esto es, utilizando las clases de dilogos estndar que nos proporciona Qt, estas clases son:
QMessageBox Permite mostrar mensajes de notificacin al usuario. QFileDialog Permite mostrar un dilogo que sirve para seleccionar un archivo o carpeta del sistema de archivos. QInputDialog Permite mostrar un dilogo con un widget para que el usuario puede introducir informacin. QColorDialog Muestra un dilogo para que el usuario pueda seleccionar un color. QPrintDialog Muestra un dilogo para especificar configuraciones de la impresora.

A continuacin mostraremos un ejemplo de uso de estos dilogos mediante una traduccin/adaptacin de el ejemplo Standar Dialogs de la documentacin oficial de Qt, esta documentacin la podemos encontrar en la direccin: 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 la ventana principal de la aplicacin de ejemplo. Esta clase esta compuesta por dos columnas de widgets, una de ellas est compuesta por botones; Cada uno de ellos servir para mostrar un dilogo estndar que nos permitir obtener un dato del usuario. La segunda columna se compone de etiquetas y en cada una de ellas escribiremos la informacin que proporcion el usuario a travs del dilogo correspondientes. Dicha ventana se muestra en la siguiente imagen.

A continuacin explicamos el cdigo del archivo Ventana.cpp:


1 2 3 4 #include #include #include #include "ventana.h" <QPushButton> <QLabel> <QGridLayout>

5 6 7 8 9 10 11 12 13 14

#include #include #include #include #include #include

<QInputDialog> <QColorDialog> <QFileDialog> <QFontDialog> <QMessageBox> <QErrorMessage>

Ventana::Ventana(){ QGridLayout* layoutPrincipal = new QGridLayout;

De las lneas 1 a 11 incluimos los archivos de cabecera que necesitamos para este ejemplo. En la lnea 13 comienza el constructor de nuestra clase. En la lnea 15 declaramos el layout con el que organizamos los componentes de nuestra ventana.
17 18 19 32 33 34 35 botonObtenerTexto = new QPushButton(trUtf8("Obtener Texto")); botonObtenerEntero = new QPushButton(trUtf8("Obtener Entero")); (...) 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 lneas 17 a 45 creamos los widgets que utilizaremos en el ejemplo. No mostramos todas las lneas debido a que el cdigo es muy repetitivo y las lneas son muy similares. En dnde escribimos () van lneas iguales a las anteriores pero para los dems widgets. El cdigo del ejemplo se puede descargar mediante los links de la parte inferior de este artculo. A partir de la lnea 17 creamos los botones que servirn para mostrar cada uno de los dilogos estndar de Qt. A partir de la lnea 32 y hasta la 45 creamos las etiquetas en las que escribiremos el valor de retorno de cada uno de los dilogos.
47 48 49 50 62 63 64 65 etiquetaObtenerTexto->setFrameStyle(QFrame::Box); etiquetaObtenerEntero->setFrameStyle(QFrame::Box); etiquetaObtenerDoble->setFrameStyle(QFrame::Box); (...) layoutPrincipal->addWidget(botonObtenerTexto, 0, 0); layoutPrincipal->addWidget(etiquetaObtenerTexto, 0, 1); layoutPrincipal->addWidget(botonObtenerEntero, 1, 0); (...)

93 94 95 96

connect(botonObtenerTexto, SIGNAL(clicked()), this, SLOT(obtenerTexto())); connect(botonObtenerEntero, SIGNAL(clicked()), this, SLOT(obtenerEntero())); connect(botonObtenerDoble, SIGNAL(clicked()), this, SLOT(obtenerDoble())); (...)

De las lneas 47 a 60 establecemos un marco para las etiquetas que mostrarn la respuesta de los dilogos. En las lneas 62 a 89 configuramos la apariencia de la interfaz de usuario utilizando un QGridLayout. Y finalmente, de las lneas 93 a 106 conectamos cada botn con su slot correspondiente, cada slot mostrar un dilogo distinto para cada botn y procesar la respuesta del usuario.

A partir de la lnea 109 comienza la implementacin de los slots, en todos ellos realizamos las siguiente acciones:
1. Creamos una variable para almacenar la informacin que ingresa el usuario por medio del dilogo. 2. Ejecutamos el dilogo para obtener la informacin del usuario y el valor de respuesta, este ltimo est determinado por el botn que presiona el usuario. 3. Evaluamos el valor de respuesta del dilogo. 4. Dependiendo del valor de la respuesta decidimos de que manera procesar la informacin capturada, si es que la hay.

A continuacin revisamos los slots que conectamos con cada uno de los botones, comenzaremos con los slots que hacen uso de los dilogos que nos ofrece la clase QInputDialog.
void Ventana::obtenerTexto() { QString texto = QInputDialog::getText(this, trUtf8(""), 109 trUtf8(""), QLineEdit::Normal, trUtf8(""), &ok); 110 111 if(ok) 112 etiquetaObtenerTexto->setText(texto); 113 } 114 115 void Ventana::obtenerEntero() 116 { 117 int entero = QInputDialog::getInt(this, trUtf8(""), 118 trUtf8(""), 42, 41, 43, 1, &ok); 119 if(ok) 120 etiquetaObtenerEntero121 >setText(QString::number(entero)); 122 } 123 124 void Ventana::obtenerDoble() 125 { 126 double doble = QInputDialog::getDouble(this, trUtf8(""), 127 trUtf8(""), 9.9, 5, 15, 2, &ok); 128 if(ok) 129 etiquetaObtenerDoble->setText(QString::number(doble)); 130 } 131 132 void Ventana::obtenerElemento() 133 { 134 QStringList listaElementos; 135 listaElementos << "Elemento 1" << "Elemento 2" << "Elemento 136 3"; 137 QString elemento = QInputDialog::getItem(this, trUtf8(""), 138 trUtf8(""), listaElementos, 0, false, &ok); if(ok) etiquetaObtenerElemento->setText(elemento); }

De la lnea 109 a la 115 implementamos el slot obtenerTexto, en l mostramos un dilogo que nos permitir obtener un valor de texto capturado por el usuario. Este dilogo lo ejecutamos mediante la funcin
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 funcin recibe como parmetros:


Un apuntador al widget que deseamos establecer como su padre. El texto que se mostrar en la barra de ttulo del dilogo. El texto que mostrar el dilogo. El modo (EchoMode) en el que se mostrar el texto ingresado. Aqui podemos establecer un valor de la enumeracin EchoMode el cual indicar si el texto debe ser visible, que no se muestre o que se muestren caracteres para enmascarar contraseas (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 botn fue presionado. Las flags (banderas u opciones) del dilogo, las cuales establecen propiedades del sistema de ventanas para un widget, como los botones que se muestran en la barra de ttulo o si debe mostrar barra de ttulo o no. Los valores posibles son parte de la enumeracin Qt::WindowFlags

Si el usuario no cierra el dilogo y en cambio presiona algn botn, entonces escribimos el valor de la respuesta en la etiqueta correspondiente. De la lnea 117 a 122 implementamos el slot obtenerEntero, en l mostramos un dilogo que contiene una spinBox que permitir al usuario establecer un valor numrico entero. Este dilogo lo ejecutamos mediante la funcin
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 )

Los primeros tres y los dos ltimos parmetros de est familia de funciones y de algunos de los otros dilogos estndar son iguales, indican el widget padre, el ttulo del dilogo, el texto que se mostrar en el dilogo, un apuntador a la variable donde se almacenar la respuesta al dilogo y una lista de flags u opciones del dilogo. A partir del cuarto parmetro y en orden, los parmetros especficos de este dilogo son:
El valor predeterminado que al que se establecer la spinbox cuando se muestre el dilogo El valor mnimo al que se puede establecer el valor de la spinbox El valor mximo al que se puede establecer el valor de la spinbox La cantidad en que se incrementar o decrementar el valor de la spinbox al presionar las flechas del extremo (step o paso)

De las lneas 124 a 129 implementamos el slot obtenerDoble, en l mostramos un dilogo muy 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 precisin. Este dilogo lo ejecutamos mediante la funcin
double QInputDialog::getDouble ( QWidget * parent, const QString & title, const QString & label, double value = 0, double min = -2147483647, double max = 2147483647, int decimals = 1, bool * ok = 0, Qt::WindowFlags flags = 0 )

Los parmetros de esta funcin son muy similares a la funcin getInt salvo por el sptimo parmetro, el cul indica el nmero de decimales del nmero, el valor por defecto es de uno.

De la lnea 131 a 138 implementamos el slot obtenerElemento, en l mostramos un dilogo que contiene una comobox que permite al usuario elegir un valor de una lista que indiquemos. Este dilogo lo ejecutamos mediante la funcin
QString QInputDialog::getItem ( QWidget * parent, const QString & title, const QString & label, const QStringList & items, int current = 0, bool editable = true, bool * ok = 0, Qt::WindowFlags flags = 0 )

Esta funcin recibe del cuarto al sexto parmetro:



140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155

Una lista de cadenas de texto que sern los elementos de la combobox La posicin del elemento seleccionado por defecto, si no se especifica ser cero Un valor booleano que indica si la combobox ser editable

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 lneas 140 a 148 implementamos el slot obtenerColor, en el mostramos un dilogo que contiene controles especializados para permitir que el usuario eliga un color. Este dilogo lo mostramos mediante la funcin
QColorDialog::getColor( const QColor & initial, QWidget * parent, const QString & title, ColorDialogOptions options = 0 )

Esta funcin recibe como parmetros:


Un objeto de la clase QColor que indica el color inicial que se establecer en el dilogo, si no se especifica ninguno el color blanco ser el seleccionado El widget padre del dilogo El ttulo del dilogo Miembros de la enumeracin ColorDialogOptions, que permiten establecer algunas propiedades del dilogo como mostrar canal alfa o usar el dilogo nativo del sistema operativo

De la lnea 150 a 155 implementamos el slot obtenerFuente, el cual muestra un dilogo que incluye controles especiales para que el usuario pueda seleccionar una fuente para el texto. Dicho dilogo se muestra mediante la funcin
QFont QFontDialog::getFont(bool *ok, QWidget *parent)

Dicha funcin tiene mltiples sobrecargas en las cuales se pueden establecer valores iniciales y configuraciones del dilogo similares a las de los dilogos anteriores pero en este ejemplo utilizamos una funcin que slo recibe como parmetros el apuntador a la variable que almacena la respuesta que da el usuario al dilogo y un apuntador al widget padre de este dilogo.

157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199

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 Cdigo 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 Cdigo Fuente C++ (*.cpp)")); if (archivos.count()) { etiquetaObtenerArchivosAbrir>setText(QString("[%1]").arg(archivos.join(", "))); } } void Ventana::obtenerArchivoGuardar() { QString nombreArchivo = QFileDialog::getSaveFileName trUtf8(""), etiquetaObtenerArchivoGuardar->text(), trUtf8("Todos los Archivos (*);;Archivos de Cabecera C/C++ (*.txt);;Archivos de Cdigo Fuente C++ (*.cpp)")); if (!nombreArchivo.isEmpty())

(this,

etiquetaObtenerArchivoGuardar->setText(nombreArchivo);

De las lneas 157 a 207 implementamos los slots que hacen uso de las funciones estticas de la clase QFileDialog. De la lnea 157 a 162 implementamos el slot obtenerDirectorioExistente en el cual ejecutamos un dilogo que mostrar una ventana de exploracin del sistema de archivos y que nos permitir seleccionar una carpeta o directorio. Este dilogo lo mostramos con la funcin
QString getExistingDirectory ( QWidget * parent = 0, const QString & caption = QString(), const QString & dir = QString(), Options options = ShowDirsOnly )

Esta funcin recibe como parmetros


Un apuntador al widget padre del dilogo El ttulo del dilogo La ruta del directorio en dnde se desea comenzar a buscar Miembros de la enumeracin QFileDialog::Options que permiten configurar opciones del dilogo como el slo mostrar directorios o utilizar un dilogo no nativo

De la lnea 176 a 187 implementamos el slot obtenerArchivoAbrir el cual funciona de manera muy similar al slot anterior con la diferencia de que este permite seleccionar un archivo en lugar de un directorio. Mostramos el dilogo utilizado en este slot con la funcin
QString QString QString options QFileDialog::getOpenFileName ( QWidget * parent = 0, const & caption = QString(), const QString & dir = QString(), const & filter = QString(), QString * selectedFilter = 0, Options = 0 )

En esta funcin el ltimo y los tres primeros parmetros son iguales al de la funcin del slot anterior. Los parmetros propios de esta funcin son:
Como cuarto parmetro, una cadena que representa los filtros que podrn ser aplicados al dilogo, este filtro determina que tipo de archivo se muestra. Para cada tipo de archivo se escribe una descripcin y entre parntesis la extensin del tipo de archivo. Separamos cada tipo de archivo mediante dos caracteres punto y coma (;;). Como quinto parmetro, una cadena que indique el filtro seleccionado actualmente.

De la lnea 176 a la 187 implementamos el slot obtenerArchivosAbrir el cual muestra un dilogo casi igual al del slot anterior con la diferencia de que este permite al usuario seleccionar ms de un archivo. Mostramos el dilogo utilizado en este slot con la funcin
QStringList QFileDialog::getOpenFileNames ( QWidget * parent = 0, const QString & caption = QString(), const QString & dir = QString(), const QString & filter = QString(), QString * selectedFilter = 0, Options options = 0 )

Los parmetros de la funcin utilizada para ejecutar el dilogo son iguales a los de la funcin utilizada para abrir un solo archivo. De la lnea 189 a 199 implementamos el slot obtenerArchivoGuardar el cual muestra un dilogo que permite guardar un archivo al usuario y eligiendo su ubicacin y especificando su nombre. El dilogo utilizado en este slot lo ejecutamos mediante la funcin
QString QString QString options QFileDialog::getSaveFileName ( QWidget * parent = 0, const & caption = QString(), const QString & dir = QString(), const & filter = QString(), QString * selectedFilter = 0, Options = 0 )

Los parmetros de esta funcin son iguales que los de la funcin utilizada para ejecutar el dilogo que permite abrir archivos. Si especificamos un nombre que coincida con el de un archivo existente se mostrar otro dilogo solicitando la confirmacin del usuario, este dilogo muestra dos botones de respuesta: Aceptar y Cancelar.
201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 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 informacin")); 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);

if (respuesta == QMessageBox::Yes) etiquetaMostrarMensajePregunta->setText(tr("S")); else if (respuesta == QMessageBox::No) etiquetaMostrarMensajePregunta->setText(tr("No")); else etiquetaMostrarMensajePregunta>setText(tr("Cancelar")); 239 } 240 241 void Ventana::mostrarMensajeAdvertencia() 242 { 243 QMessageBox msgBox(QMessageBox::Warning, 244 trUtf8("QMessageBox::warning()"), 245 trUtf8("Este es un mensaje de 246 advertencia"), 0, this); 247 msgBox.addButton(trUtf8("Guardar Otra Vez"), 248 QMessageBox::AcceptRole); 249 msgBox.addButton(trUtf8("Continuar"), 250 QMessageBox::RejectRole); 251 if (msgBox.exec() == QMessageBox::AcceptRole) etiquetaMostrarMensajeAdvertencia->setText(tr("Guardar Otra Vez")); else etiquetaMostrarMensajeAdvertencia>setText(tr("Continuar")); }

A partir de la lnea 201 y hasta el fin del archivo en la lnea 251 implementamos los slots que muestran los dilogos de la case QMessageBox. Entre las lneas 201 y 215 implementamos el slot mostrarMensajeCritico el cual permite mostrar un dilogo con un icono de error que normalmente sirve para indicar que ocurri algn error grave en la aplicacin. Mostramos este dilogo mediante la funcin
StandardButton QMessageBox::critical ( QWidget * parent, const QString & title, const QString & text, StandardButtons buttons = Ok, StandardButton defaultButton = NoButton )

Dicha funcin nos devuelve un valor de la enumeracin StandarButttons, la cual contiene todos los posibles valores que devuelve un dilogo al presionar cada uno de los botones disponibles, como: Aceptar, Cancelar, Reintentar, S, S a todo, No, Cancelar. Las cuatro funciones de la clase QMessageBox que revisaremos y que nos sirven para mostrar un dilogo de informacin reciben los mismos parmetros, los cuales son:
Un apuntador al widget padre del dilogo El ttulo del dilogo

El texto que deseamos mostrar en el dilogo Una lista de valores de la enumeracin StandarButton separadados por caracteres 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 botn correspondiente Un valor de la enumeracin StandarButtons el cual indica que botn se establecer como predeterminado, es decir sobre cual se har un efectro de clic al presionar la tecla enter al estar el dilgo activo

Entre las lneas 217 y 225 implementamos el slot mostrarMensajeInformacion en el cual mostramos un dilogo que sirve para mostrar informacin al usuario, como un aviso sobre la conclusin de una tarea o una notificacin de algn evento. Mostramos el dilogo utilizado mediante la funcin
StandardButton QMessageBox::information ( QWidget * parent, const QString & title, const QString & text, StandardButtons buttons = Ok, StandardButton defaultButton = NoButton )

De la lnea 227 a 239 implementamos el slot mostrarMensajePregunta en el cual mostramos un dilogo con icono de un signo de interrogacin, este dilogo sirve para realizar una pregunta al usuario o solicitar su confirmacin u aprobacin para un proceso, como al guardar o borrar un archivo. Mostramos este dilogo mediante la funcin
StandardButton QMessageBox::question ( QWidget * parent, const QString & title, const QString & text, StandardButtons buttons = Ok, StandardButton defaultButton = NoButton )

Y finalmente de le la lnea 241 a la 251 implementamos el slot mostrarMensajeAdvertencia en el cual mostramos un dilogo con que sirve para mostrar un mensaje de advertencia, como informacin sobre un error poco grave. Este dilogo lo mostramos mediante la funcin
StandardButton QMessageBox::warning ( QWidget * parent, const QString & title, const QString & text, StandardButtons buttons = Ok, StandardButton defaultButton = NoButton )

Con esa funcin concluimos la revisin del cdigo del archivo Ventana.cpp. En el archivo main.cpp simplemente creamos un objeto de esta clase y lo mostramos en pantalla. Eso es todo en este artculo. En la siguiente parte de este tutorial veremos como utilizar los widgets QListWidget, QTableWidget y QTreeWidget, los cuales nos permiten visualizar un conjunto 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 aplicacin


En el artculo anterior de este tutorial vimos como implementar la funcionalidad de una aplicacin grfica de Qt utilizando seales y slots. En este artculo revisaremos a detalle un widget especial, QMainWindow, el cul posee caractersticas especiales para ser utilizado como 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 mens, los

cuales estn compuestos por elementos de texto o etiquetas que indican las acciones que puede realizar la aplicacin y que se ejecutan al hacer clic sobre ellas. Normalmente slo existe una de ellas en la ventana y est colocada en la parte superior, debajo de la barra de ttulo. Algunos ejemplos muy conocidos de mens que suelen colocarse en esta barra son Archivo, Edicin, Herramientas o Ayuda.

Toolbars al igual que la barra de mens, esta clase de barras, conocida como barra de herramientas est compuesta por las acciones que puede realizar la aplicacin, con la diferencia de que en esta barra dichas acciones se muestran mediante iconos en lugar de etiquetas. Estas barras suelen estar ubicadas debajo de la barra de mens y podemos encontrar una o ms de estas barras en una ventana. Un ejemplo muy conocido de iconos colocados en este tipo de barras son los de Guardar, representado por un diskette o Imprimir, representado por una impresora.

Status Bar Esta barra, conocida como barra estatus o de estado, normalmente est colocada en la parte inferior de la ventana, en ella se muestran mensajes informativos sobre el estado de la aplicacin, las acciones que est realizando o la descripcin del elemento al que estemos apuntando con el mouse. Dock Widgets Este es un tipo de widgets que pueden ser acoplados o ajustados alrededor del widget central de una aplicacin o permitir que floten libremente en el escritorio, al igual que las barras de herramientas contienen iconos y botones que permiten ejecutar acciones que proporciona la aplicacin.

Central Widget Este widget representa el rea de trabajo de una aplicacin, como la tabla de celdas de una aplicacin en hoja de clculo o el rea de texto de un procesador de textos.

Podemos reconocer ests secciones en un buen nmero de aplicaciones, como ejemplo presentamos la ventana de Open Office Writer (clic para ampliar).

A continuacin mostraremos un sencillo ejemplo de una aplicacin que basada en una QMainWindow, la cual contendr una etiqueta como widget central la cual cambiar el texto que muestra dependiendo de la accin que ejecutemos, estas acciones se encontrarn en una barra de mens y una barra de herramientas tambin incluiremos una barra de estatus. La aplicacin est compuesta por los siguientes tres archivos:
ventanaprincipal.h es el archivo de encabezado de la clase VentanaPrincipal, contiene la declaracion de las variables y la definicin de las funciones que utilizaremos en esta aplicacin. ventanaprincipal.cpp es el archivo fuente de la clase VentanaPrincipal, contiene la implementacin de las funciones declaradas en el archivo de encabezado. main.cpp

A continuacin revisaremos a detalle los archivos de la aplicacin, slo explicaremos las secciones que no hayan sido revisadas en partes anteriores de este tutorial o que sean relevantes en este contexto ventanaprincipal.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 #ifndef VENTANAPRINCIPAL_H #define VENTANAPRINCIPAL_H #include <QMainWindow> class class class class QLabel; QToolBar; QAction; QMenu;

class VentanaPrincipal : public QMainWindow { Q_OBJECT

15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34

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 lnea 4 incluimos el archivo de cabecera QMainWindow el cual contiene la definicin de la clase en la que basaremos nuestra ventana principal. En la lnea 11 definimos nuestra clase VentanaPrincipal e indicamos que heredar de QMainWindow. De la lneas 18 a 22 declaramos los slots por medio de los cuales implementaremos la funcionalidad de nuestra aplicacin. Y finalmente de las lneas 24 a 32 declaramos las variables que utilizaremos en la aplicacin. ventanaprincipal.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 #include "ventanaprincipal.h" #include #include #include #include #include <QMenuBar> <QToolBar> <QLabel> <QStatusBar> <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"));

24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80

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 aplicacin")); accionAcercaDe = new QAction(QIcon("iconos/salir.png"), trUtf8("&Acerca de"), this); accionAcercaDe->setShortcut(QKeySequence("Ctrl+d")); accionAcercaDe->setStatusTip(trUtf8("Informacin sobre esta aplicacin")); 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("Accin \"Nuevo\" lanzada")); this->resize(QSize(widgetCentral->sizeHint().width(), 200)); } void VentanaPrincipal::accionAbrirLanzada() { widgetCentral->setText(trUtf8("Accin \"Abrir\" lanzada")); this->resize(QSize(widgetCentral->sizeHint().width(), 200)); }

81 82 83 84 85

void VentanaPrincipal::accionAcercaDeLanzada() { QMessageBox::about(this, this->windowTitle(), trUtf8("Aqu se debe colocar informacin sobre la aplicacin y la compaia que la desarolla\n\nTutoriales, artculos y enlaces de programacin en:\nhttp://www.programacion-linux.com")); } void VentanaPrincipal::accionSalirLanzada() { exit(0); }

De las lneas 1 a 7 incluimos los archivos de cabecera necesarios para implementar la aplicacin. En las lnea 11 inicializamos la variable menuArchivo la cual representa un men que podemos incluir en la barra de mens de la QMainWindow, para lograrlo utilizamos las funciones
QMenuBar* QMainWindow::menuBar()

Devuelve una referencia a una barra de mens que es creada al llamar a la funcin por primera vez.
QMenu* QMenuBar::addMenu(QString &texto)

Devuelve una referencia a un men que se crear al llamar a la funcin y que mostrar en pantalla el texto indicado en la cadena de caracteres que se pasa como parmetro. En la lnea 12 realizamos lo mismo para el men Ayuda. En la lnea 14 inicializamos la variable que representa a una barra de herramientas. La funcin utilizada es:
QToolBar* QMainWindow::addToolBar(QString &texto);

y trabaja de manera muy similar a las descritas anteriormente, es decir, devuelve una referencia a una QToolBara que se crea cuando se llama a la funcin y que mostrar en pantalla la cadena que se pasa como parmetro. En la lnea 16 inicializamos la etiqueta que ser utilizada como widget central en la aplicacin. Y en la lnea 17 establecemos la fuente que queremos que ocupe la etiqueta, esto se hace mediante la instruccin:
QLabel::setFont(QFont(QString &fuente, int tamanio));

La cual recibe como parmetros un objeto QFont, el cual representa una fuente de texto y que a su vez recibe como parmetros el nombre de la fuente y el tamao de la misma. En la lnea 19 inicializamos nuestra variable accionNuevo, del tipo QAction, mediante el constructor de la clase
QAction::QAction(QIcon(QString &archivo), QString &texto, QWidget* padre)

Este constructor recibe como parmetros un objeto QIcon, el cual representa un icono que se mostrar cuando la accin sea colocada dentro de una barra de herramientas y que a su vez recibe como parmetro una cadena de texto con la direccin dnde se encuentra el archivo de imgen que mostrar el icono, el segundo parmetro del constructor de la clase

QAction es una cadena que indica el texto que se mostrar cuando la accin sea colocada dentro de una barra de mens y el ltimo parmetro es el widget padre de la accin. Antes de seguir debemos definir el concepto de QAction: Una QAction es una representacin abstracta de un comando de la aplicacin que puede ser ejecutado por el usuario. En muchas aplicaciones los mismos comandos, acciones o funciones pueden ser ejecutados de diferentes maneras, ya sea mediante un elemento de la barra de mens, un icono de alguna barra de herramientas o una combinacin de teclas, por mencionar algunos ejemplos. Una QAction nos es muy til en este tipo de situacin ya que puede estar asociada a mltiples widgets, gracias a esto ser posible proporcionar la misma funcin en distintos lugares de la aplicacin y de manera sincronizada, entonces podemos decir que una QAction proporciona una interfaz comn para la ejecucin de los comandos de la aplicacin. Siguiendo con el cdigo, en la lnea 20 establecemos un atajo de teclado para nuestra accin Nuevo, mediante la funcin
QAction::setShortcut(const QKeySecuence secuencia)

la cual recibe como parmetro un elemento de la enumeracin QKeySecuence, dicha enumeracin nos proporciona combinaciones estndar de teclas dependiendo de la configuracin del sistema operativo en el que nos encontremos. Por ejemplo en el caso de mi sistemas operativo el elemento QKeySecuence::New esta relacionado con la combinacin de teclas Ctrl+N sin embargo esto puede ser distinto en otro sistema operativo, pero al utilizar esta enumeracin Qt se encargar de administrarlo y en caso de que se requiera, asociarlo a otra combinacin de teclas ms adecuada en esa situacin. En la lnea 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 accin correspondiente. Esto se logra mediante la funcin:
QAction::setStatusTip(QString &texto)

La cual recibe como parmetro una cadena con el texto que deseamos mostrar. En las lneas 23 a 33 realizamos lo mismo para las acciones restantes. En las lneas 35 a 38 agregamos tres de las acciones que creamos al men Archivo. Esto lo hacemos a travs de la funcin
QMenu::addAction(QAction* accion)

Con el fin de lograr un diseod e interfaz de usuario ms claro y atractivo en la lnea 37 agregamos un separardor, utilizando la funcin
QMenu::addSeparator()

Un separador es una lnea vertical u horizontal que separa las acciones que est colocadas dentro del mismo men o barra de herramientas pero que pueden ser ubicadas en una categora especfica o diferente del resto de las acciones del mismo men o barra de herramientas. En la lnea 40 agregamos la accin AcercaDe al men Ayuda. En las lneas 42 a 45 agregamos las acciones a la barra de herramientas de la aplicacin utilizando las mismas funciones que utilizamos para agregarlas a los mens. En la lnea 48 creamos la barra de estatus mediante la funcin

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 lnea utilizamos la funcin
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 aplicacin puede comenzar a utilizarse. En las lneas 52 y 53 conectamos la accin accionNuevo con su slot correspondiente, esto lo realizamos mediante la funcin connect(), la cual revisamos a detalle en un artculo anterior. Debido a que una accin puede estar asociada a mltiples widgets no siempre ser lanzada de la misma forma, debido a ello Qt nos proporciona la seal triggered() (lanzada o disparada) la cual se emitir cada vez que un widget asociado a la seal sea activado, por ejemplo un clic sobre un botn lanzar una accin asociada al mismo mientras que una combinacin de teclas lanzar dicha accin al ser presionada por el usuario. En las lneas 55 a 62 conectamos las acciones restantes a sus respectivos slots. En la lnea 65 comienza la implementacin de los slots, los slots accionNuevoLanzada y accionAbriLanzada cambiarn el texto que se muestra en la etiqueta utilizada como widget central y redimensionarn la ventana para ajustarla al nuevo texto mostrado. El cambio de texto de la etiqueta se realiza mediante la funcin
QLabel::setText(QString &texto)

la cual recibe como parmetro una cadena de caracteres con el texto que se desea mostrar. El cambio de tamao de la ventana se realiza mediante la funcin
QMainWindow::resize(QSize(int width, int height))

esta funcin recibe como parmetro un objeto QSize, el cual es una estructura que incluye el ancho y alto de un widget y que a su vez recibe como parmetros dos enteros indicando el ancho y alto del widget, respectivamente. Tambin utilizamos la funcin sizeHint() la cual devuelve un objeto QSize con el tamao requerido por el widget sobre el que se llamo la funcin. En la lnea 77 comienza la implementacin del slot asociado a la accin acercaDe, en la lnea 79 indicamos que al dispararse dicha accin se mostrar el conocido dilogo acerca de el cul contiene informacin sobre la aplicacin como versino fecha de lanzamiento y sobre la compaia que creo la aplicacin. Finalmente en las lneas 82 a 85 implementamos el slot asociado a la accin salir, en la lnea 84 utilizamos la funcin exit(int codigo) para indicar que deseamos salir de la aplicacin, la aplicacin devolver un cdigo el cdigo de error indicado como parmetro. Normalmente un valor de cero indica que la aplicacin termino normalmente, es decir, sin ningn error. main.cpp
1 #include "ventanaprincipal.h" 2 #include <QApplication> 3 4 int main(int argc, char* argv[])

5 { 6 7 8 9 10 11 12 13 }

QApplication app(argc, argv); VentanaPrincipal* ventanaPrincipal = new VentanaPrincipal; ventanaPrincipal->show(); return app.exec();

En la lnea 1 incluimos el archivo de cabecera de la clase VentanaPrincipal, mientras que en la lnea 8 creamos e inicializamos un objeto de dicha clase, y finalmente en la lnea 10 mostramos nuestra ventana principal. Al ejecutar esta aplicacin de ejemplo obtendremos algo parecido a lo mostrado en las siguientes imagenes:

Es todo en este artculo, en la siguiente parte del tutorial veremos como implementar un widget personalizado, el cual podremos utilizar en futuras aplicaciones que desarrollemos.

Tutorial de Qt 4: Layouts, organizacin de los Widgets


En el ejemplo anterior realizamos nuestra primera aplicacin en Qt, el clsico 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 slo servira de ejemplo, pero en l se pueden apreciar serias deficiencias, tal vez la ms notoria es que slo es posible utilizar un elemento de interfaz grfica (widget) a la vez, el cual en nuestro caso fue una etiqueta. En este artculo veremos la forma de solucionar esto: utilizando Layouts. Los Layouts son objetos que nos permiten organizar los widgets dentro de una ventana, en Qt disponemos de los siguientes tipos bsicos de Layouts:
QHBoxLayout QVBoxLayout QGridLayout QFormLayout

A continuacin describiremos brevemente estos layouts y mostraremos un ejemplo bsico de su uso. QHBoxLayout Nos permite ordenar los widgets en filas, es decir, de manera horizontal.

El cdigo para crear una aplicacin con un layout como el de la imagen anterior es el siguiente, explicaremos slo las lneas de cdigo que no hayan sido vistas a detalle en partes anteriores del tutorial:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 #include #include #include #include #include <QObject> <QApplication> <QDialog> <QHBoxLayout> <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("Botn 1")); QPushButton *boton2 = new QPushButton(QObject::trUtf8("Botn 2")); QPushButton *boton3 = new QPushButton(QObject::trUtf8("Botn 3")); layout->addWidget(boton1); layout->addWidget(boton2); layout->addWidget(boton3); ventana->setLayout(layout); ventana->setWindowTitle("QHBoxLayout"); ventana->show(); return app.exec(); }

Las lneas 1 a 5 importan las bibliotecas necesarias para esta aplicacin, QObject nos proveer de la funcin trUtf8() necesaria para escribir cadenas con caracteres Unicode, en nuestro caso, caracteres propios del espaol como la , o el acento (tilde). QDialog es una clase que representa un dilogo de aplicacin. Utilizamos un dilogo en lugar de una ventana principal buscando mantener la simplicidad del ejemplo. Un dilogo es una ventana mediante la cual el usuario y la aplicacin se comunican. Algunos de sus usos son:
Informar al usuario sobre la ocurrencia de algn evento relevante como una notificacin al terminar un proceso o un error al realizarlo. Solicitar confirmacin para realizar alguna accin como borrar o guardar un archivo. Solicitar informacin, como la palabra a buscar en un dilogo de buscar y reemplazar.

QHBoxLayout es una clase que representa a nuestro layout horizontal. QPushButton es una clase que representa a un botn estndar.
11 12 13 QDialog *ventana = new QDialog(); QHBoxLayout *layout = new QHBoxLayout(); QPushButton *boton1 = new QPushButton(QObject::trUtf8("Botn 1"));

En las lneas 11 a 13 creamos un nuevo dilogo, layout y botn mediante la sentencia new para ejecutar el constructor de cada clase, en este caso el constructor del botn es el nico que recibe parmetros, este parmetro es una cadena de texto que contenga la etiqueta que debe mostrar el botn. Las lneas 14 y 15 crean los otros botones de la misma forma.
17 18 19 layout->addWidget(boton1); layout->addWidget(boton2); layout->addWidget(boton3);

En las lneas 17 a 19 colocamos los botones dentro de nuestro layout mediante la funcin
addWidget(QWidget *widget, int stretch=0, Qt::Alignment aling=0)

Esta funcin recibe como parmetros un apuntador al widget que deseamos agregar, un entero que indica el indice de flexibilidad (stretch) del widget y un elemento de la enumeracin Qt::Alignment, los ltimos dos parmetros pueden omitirse y en caso de hacerlo se les asiga el valor de cero. El stretch indica la proporcin de espacio disponible en el layout que el widget ocupar, es relativo al stretch indicado en los otros widgets que estn dentro del layout, entre mayor sea el valor de stretch mayor ser el espacio que ocupar el widget. La enumeracin Qt:Alignment indica la alineacin que tendr el widget y 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 en este layout el primer botn de izquierda a derecha (la direccin por default de este layout) es boton1 seguido de boton2 y por ltimo boton3. Si queremos invertir el orden de los widgets podemos escribir las instrucciones en orden inverso o podemos indicar que nuestros widgets se aadan de derecha a izquierda con la instruccin
setDirection(QBoxLayout:RightToLeft) 17 ventana->setLayout(layout); 18 ventana->setWindowTitle("QHBoxLayout");

En la lnea 17 establecemos nuestro layout como el principal de la ventana, es decir el que indicar como se muestran los widgets en esa ventana. Y por ltimo en la lnea 18 indicamos el ttulo que queremos que muestre nuestra ventana, si no se especifica se utilizar el del nombre del archivo. QVBoxLayout Nos permite ordenar los widgets en columnas, es decir, de manera vertical.

El cdigo para crear una aplicacin con un layout como el de la imagen anterior es el siguiente:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 #include #include #include #include #include <QObject> <QApplication> <QDialog> <QVBoxLayout> <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("Botn 1")); QPushButton *boton2 = new QPushButton(QObject::trUtf8("Botn 2")); QPushButton *boton3 = new QPushButton(QObject::trUtf8("Botn 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 que nuestro objeto layout ahora es de tipo QVBoxLayout, el resultado de esto es que los widgets ahora se organizan de acuerdo a las reglas de este layout, es decir, de arriba hacia abajo. Si queremos invertir el orden en que se agregan los widgets al layout utilizamos la instruccin
setDirection(QBoxLayout::BottomToTop);

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

El cdigo para crear una aplicacin con un layout similar al de la imagen es:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 #include #include #include #include #include <QObject> <QApplication> <QDialog> <QGridLayout> <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("Botn 1")); QPushButton *boton2 = new QPushButton(QObject::trUtf8("Botn 2")); QPushButton *boton3 = new QPushButton(QObject::trUtf8("Botn 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 clase QGridLayout. La forma de agregar los widgets a este tipo de layout es ligeramente distinta, ahora lo haremos mediante la funcin
addWidget(QWidget *widget, int fila, int columna, Qt::Alignment align=0);

Esta funcin recibe como parmetros un apuntador al widget que deseamos agregar, dos enteros que indican la fila y columna, respectivamente, de la celda sobre la cual queremos agregar el widget en cuestin y un valor de la enumeracin Qt::Alignment. Las filas y columnas comienzan a contarse desde cero de tal manera que la primera celda en la esquina superior izquierda tiene la posicin fila=0, columna=0.
17 18 19 layout->addWidget(boton1, 0, 0); layout->addWidget(boton2, 0, 1); layout->addWidget(boton3, 1, 0);

En la lnea 17 colocamos al primer botn en la celda definida por la interseccin de la fila cero con la columna cero, es decir, posicin 0,0. Luego colocamos al boton2 y boton3 en las celdas 0,1 y 1,0 respectivamente.

El espacio vaco en la celda 1,1 se genera debido a que el QGridLayout crea tantas divisiones de filas y columnas como el nmero mximo de filas o columnas que indiquemos, en este caso dos, debido a la existencia de las filas y columnas uno y cero. Por ejemplo, si aadieramos los botones al layout mediante las lneas
layout->addWidget(boton1, 0, 0); layout->addWidget(boton2, 1, 1); layout->addWidget(boton3, 2, 2);

Obtendramos el siguiente resultado:

Sin embargo habr que tener en cuenta que las filas o columnas extras no sern visibles a menos que establezcamos el alto/ancho mnimo de cada fila/columna o que coloquemos un widget en la fila/columna correspondiente, en este ltimo caso (que es lo que ha ocurrido en los dos ejemplos anteriores) el QGridLayout asigna automticamente el alto/ancho mnimo de esta fila/columna con un valor igual al mnimo requerido por el widget en cuestin. Podemos establecer el ancho mnimo de una columna y el alto mnimo de una fila con las funciones:
setColumnMinimumWidth(int columna, int anchoMinimo ) setRowMinimumHeight(int fila, int altoMinimo)

Por ejemplo si aadieramos los botones al layout mediante el siguiente cdigo:


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

Se crearan cuatro filas y cuatro columnas, es decir, una fila y columna ms que en el ejemplo anterior, pero al ejecutar el programa obtendramos el mismo resultado que se muestra en la imagen pasada. Esto ocurre debido a que aunque la fila y columna con el nmero dos existen, estas tienen un alto y ancho de cero ya que no hemos colocado ningn widget en ellas ni hemos establecido el tamao mnimo para ellas. Pero si despus de la lnea dnde agregamos el ltimo botn al layout aadimos las lneas:
layout->setColumnMinimumWidth(2, 60); layout->setRowMinimumHeight(2, 20);

Obtendramos el siguiente resultado:

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

El cdigo para crear una aplicacin con un layout como el de la imagen anterior es el siguiente:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 #include #include #include #include #include <QObject> <QApplication> <QDialog> <QFormLayout> <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("Botn 1")); QPushButton *boton2 = new QPushButton(QObject::trUtf8("Botn 2")); QPushButton *boton3 = new QPushButton(QObject::trUtf8("Botn 3")); layout->addRow(QObject::trUtf8("Botn 1:"), boton1); layout->addRow(QObject::trUtf8("Botn 2:"), boton2); layout->addRow(QObject::trUtf8("Botn 3:"), boton3); ventana->setLayout(layout); ventana->setWindowTitle("QVBoxLayout"); ventana->show(); } return app.exec();

En este caso nuestro layout ser del tipo QFormLayout y para aadir widgets utilizarermos la funcin
addRow(QLabel *etiqueta, QWidget *widget);

aunque tambin es posible utilizar la siguiente funcin 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 layout->addRow(QObject::trUtf8("Botn 1:"), boton1); 18 layout->addRow(QObject::trUtf8("Botn 2:"), boton2); 19 layout->addRow(QObject::trUtf8("Botn 3:"), boton3);

En las lneas 17 a 19 agregamos los widgets al layout, utilizamos la versin sobrecargada de addRow() en la que el primer parmetro es una cadena de texto con el fin de ahorrar cdigo, 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 layout es muy til, por ejemplo, en la creacin de formularios para la solicitud de informacin (como un registro de usuarios o un formulario de comentarios) en dnde debemos de indicar que informacin debe de capturar el usuario en cada campo. Layouts Anidados Normalmente las aplicaciones que desarrollemos no tendrn una interfaz tan sencilla como para ser diseadas utilizando slo un layout, para organizar los widgets de maneras ms complejas utilizamos layouts anidados, es decir, un layout dentro de otro. La funcin que nos permite anidar layouts depende del tipo de layout que estemos utilizando, para QHBoxLayout y QVBoxLayout la funcin es:
addLayout(QLayout *layout, int Qt::Alignment align=0)

Para el QGridLayout adems debemos especificar la fila y columna de la celda dnde deseamos agregar el layout, de la siguiente forma
addLayout(QLayout *layout, int fila, int columna, Qt::Alignment align=0)

Para el QFormLayout se utiliza una funcin sobrecargada de addRow(), en una de las siguientes formas, dependiendo de la apariencia que deseemos lograr:
addRow(QLabel *label, QLayout *layout) addRow(QString &amp;texto, QLayout *layout)

Est funcin recibe como parmetros un apuntador a la etiqueta que contiene el texto que describe al layout o simplemente una QString con ese texto y un apuntador al layout que deseamos agregar.
addRow(QLayout *layout)

Esta funcin recibe cmo parmetro un apuntador al layout que deseamos agregar. A continuacin mostraremos un sencillo ejemplo de anidacin de layouts para crear una interfaz de usuario muy conocida: un formulario de inicio de sesin.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48

#include #include #include #include #include #include #include

<QApplication> <QHBoxLayout> <QVBoxLayout> <QLabel> <QLineEdit> <QPushButton> <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 Sesin")); ventana->show(); return app.exec(); }

Al ejecutar este cdigo obtendremos una salida parecida a la siguiente imagen

En las lneas 1 a 7 incluimos los archivos de cabecera necesarios para desarrollar la aplicacin, mientras que en las lneas 13 a 26 creamos los widgets que utilizaremos. En las lneas 28 y 29 colocamos los widgets del campo usuario en un QHBoxLayout, lo mismo hacemos para los campos de contrasea y para los botones. Con el fin de lograr una interfaz ms agradable alineamos los botones a la derecha insertando un espacio en blanco al principio del QHBoxLayout mediante la instruccin
addStretch(int stretch=0); 38 layoutPrincipal->addLayout(layoutUsuario); 39 layoutPrincipal->addLayout(layoutContrasenia); 40 layoutPrincipal->addLayout(layoutBotones); 41 42 ventana->setLayout(layoutPrincipal);

A partir de la lnea 38 agregamos en el layout principal (el cual es un QVBoxLayout) el layout que contiene los controles de usuario, seguido por el que contiene los controles de contrasea y por ltimo el que contiene los botones y finalmente en la lnea 40 establecemos el layout principal de nuestra apliciacin. Es posible disear una interfaz de usuario utilizando distintas combinaciones de layouts, es cuestin de tiempo y experiencia poder encontrar aquella que sea ms fcil y rpida de crear o la que se adapte mejor a las necesidades de nuestra aplicacin. Para el ejemplo anterior un mejor diseo (considerando que requiere menos lneas) puede lograrse utilizando un QFormLayout en lugar de los primeros dos QHBoxLayout. El cdigo es el siguiente:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 #include #include #include #include #include #include <QApplication> <QHBoxLayout> <QFormLayout> <QLineEdit> <QPushButton> <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");

21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 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 Sesin")); ventana->setWindowFlags(Qt::Window); ventana->show(); return app.exec(); }

Al ejecutar este cdigo obtenemos una salida similar a la siguiente

La cual tiene una apariencia muy similar a la del ejemplo anterior y que en mi opinin incluso se ve mejor, pero lo importante es que el nmero de lneas utilizadas se redujo un poco, pero es de suponer que en una aplicacin de mayor tamao el ahorro de lneas de cdigo tambin 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 interfaz grfica de usuario, escrito completamente en C, no se encuentra orientado a objetos, sin embargo simula estarlo, al estar programado en C es bastante flexible con otros lenguajes y facilmente adaptable, la interfaz grafica de Gnome (el entorno de escritorio de Ubuntu) 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 sencillo ya 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 para que todo funcione correctamente. Instalacion de Gtk+ con paquetes de distribucin (O la ruta escnica) El primer paso es conseguir el paquete de distribucin de la pgina www.gtk.org de la seccin de descargas de la misma, el segundo es extraerlo a la carpeta donde tendremos todos nuestros archivos de origen, esto lo hacemos con los comandos:
tar xvfz gtk+-2.0.0.tar.gz tar xvfj gtk+-2.0.0.tar.bz2

Despues de hacer esto nos ubicamos en la carpeta donde se contienen todos los demas archivos y ejecutamos el script llamado configure el cual crea archivos makefile adecuados 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:
make make install

Despues de esto puede que sea necesario hacerle saber al sistema operativo acerca de las nuevas librerias dinmicas esto lo hacemos ejecutando:
ldconfig

Una vez hecho esto al fin hemos conseguido instalar Gtk+ en uestra maquina con Linux, si ocurrel agun fallo a pesar de que ya se encuentra instalado Gtk+, lo mas probable es que se trate de alguna libreria de la cual depende gtk para compilar/ejecutar, la manera mas fcil de 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+.

Potrebbero piacerti anche