0% encontró este documento útil (0 votos)
4K vistas47 páginas

Tutorial de Qt: Primer Programa "Hola Mundo"

Este documento presenta un tutorial sobre la creación de una aplicación Qt muy básica que muestra el texto "Hola Mundo!". Explica cómo incluir las cabeceras necesarias, crear un objeto QApplication, agregar un botón con el texto y mostrarlo, y ejecutar la aplicación. También cubre cómo compilar y ejecutar el programa utilizando qmake.

Cargado por

cadavid219
Derechos de autor
© Attribution Non-Commercial (BY-NC)
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como DOCX, PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
4K vistas47 páginas

Tutorial de Qt: Primer Programa "Hola Mundo"

Este documento presenta un tutorial sobre la creación de una aplicación Qt muy básica que muestra el texto "Hola Mundo!". Explica cómo incluir las cabeceras necesarias, crear un objeto QApplication, agregar un botón con el texto y mostrarlo, y ejecutar la aplicación. También cubre cómo compilar y ejecutar el programa utilizando qmake.

Cargado por

cadavid219
Derechos de autor
© Attribution Non-Commercial (BY-NC)
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como DOCX, PDF, TXT o lee en línea desde Scribd

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!");

[Link]();
return [Link]();
}

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[])


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

[Link]();

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

visible.
return [Link]();
}

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


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

Resumen
Este ejemplo es una continuación de la ventana creada en el capitulo 1. Vamos a hacer que
la 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);
QPushButton quit("Quit");
[Link](75, 30);
[Link](QFont("Times", 18, QFont::Bold));

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

[Link]();
return [Link]();
}

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.
[Link](75, 30);

Hemos elegido otro tamaño para el botón ya que el texto es algo mas corto que "Hola
Mundo!". También podríamos haber usado QFontMetrics para establecer el tamaño
adecuado, o permitir que QPushButton eligiera un tamaño razonable por defecto.
[Link](QFont("Times", 18, QFont::Bold));

Elegimos una nueva fuente para el botón: Times y negrita de 18 puntos. También es posible
cambiar 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 que


connect() 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 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 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.
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).
Resumen
En el tercer capítulo 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;
[Link](200, 120);

QPushButton quit("Quit", &window);


[Link](QFont("Times", 18, QFont::Bold));
[Link](10, 40, 180, 40);
QObject::connect(&quit, SIGNAL(clicked()), &app, SLOT(quit()));

[Link]();
return [Link]();
}

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 de
la interfaz de usuario. Un widget es el átomo de la interfaz de usuario: captura el ratón, el
teclado y otros eventos del administrador de ventanas, y dibuja una representación 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 posición inicial en la pantalla está
controlada por el administrador de ventanas.
[Link](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 posición (0, 0).
[Link](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 botón (relativas al widget padre), y
los dos últimos son la anchura y la altura del botón. El resultado es un botón que ocupa
desde la posición (10, 40) hasta la posición (190, 80).
[Link]();
Cuando mostramos un widget padre, este llamará a la función 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 documentación de QObject recordarán
que 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 otra
cuando el botón sale de su ámbito.
No hay necesidad de preocuparse en este caso, ya que el código es correcto. De todas
formas, existe un caso en el que el programador debe ser consciente del orden de la
destrucción de objetos en la pila (puedes ver la explicación del orden de
construcció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 se
mantiene 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 intentas
hacer la ventana muy pequeña?
Resumen
En este capítulo vamos a ver como crear nuestro propio widget y como controlar el tamaño
mí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;
[Link]();
return [Link]();
}

Explicación
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 capítulo anterior).
La clase solo tiene un miembro, el constructor (además de los miembros heredados de
QWdiget). 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 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 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 el
siguiente capítulo 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 función tr() marca la cadena "Quit" para que pueda ser traducida, haciendo posible
cambiarla 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 tu
aplicación 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á automáticamente cuando el objeto
MyWdiget sea destruido (No hay nada malo en borrar un hijo cuando lo desees, el hijo
avisará 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, y
apunta a la instancia única de QApplication en la aplicación.
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
MyWidget widget;
[Link]();
return [Link]();
}
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 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 añadir mas botones o a incluir otros widgets a parte de QPushButton.
Resumen
En el quinto capítulo 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 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);


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;
[Link]();
return [Link]();
}

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. Vamos
a hacer que lcd muestre dos dígitos 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 señal 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 señal está conectada al slot display() del LCD, se llamará al
slot cuando la señal sea emitida. Ten en cuenta que ninguno de los objetos sabe sobre el
otro (esencial en la programación 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 geometría de sus widgets hijos. Por
esta razón ya no necesitamos especificar las coordenadas en la pantalla para cada widget
hijo tal como hicimos en el capítulo 4. Además, usar un layout asegura que se
redimensionen los widgets hijos cuando la ventana se redimensione. Por tanto añadimos los
widgets quit, lcd y slider al layout mediante QBoxLayout::addWidget().
La función 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 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 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 añadir a un layout, lo cual hace que el layout sea el
responsable 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 cambia
el tamaño de la ventana (porque puede), pero los otros siguen teniendo el mismo tamaño (lo
contrario 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 base
del número (decimal, hexadecimal, octal o binaria).
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
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 [Link]();
12 }
1 #include <QApplication>
2 #include <QLabel>
Incluimos los archivos de cabecera que utilizaremos para el ejemplo, QApplication es una
clase que representa una aplicación gráfica de Qt, es la encargada de administrar el flujo de
ejecución y la configuración principal de la aplicación. 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 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 contiene
el número 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 parámetros los argumentos de línea
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 [Link]();
Inicia el hilo principal de la aplicación a partir de este momento el framework toma el
control 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 al
sistema 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 ejecutado
exitosamente.
Compilación y Ejecución
Guardamos el archivo como [Link] o cualquier otro nombre con extensión “.cpp”.
Abrimos una terminal en la ubicación de nuestro archivo [Link] y ejecutamos los
siguientes comandos.
qmake -project
Crea un archivo de proyecto para nuestra aplicación
qmake [Link]
Crea un archivo de proyecto específico para la plataforma o SO en el que estamos
trabajando
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 la
funcionalidad de estas clases y gestionando las respuestas que recibimos a través de la
función QDialog::exec()
En este artículo veremos la segunda forma de utilizar diálogos en una aplicación de Qt, esto
es, 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 un
archivo o carpeta del sistema de archivos.
• QInputDialog Permite mostrar un diálogo con un widget para que el
usuario puede introducir información.
• QColorDialog Muestra un diálogo para que el usuario pueda seleccionar
un color.
• QPrintDialog Muestra un diálogo para especificar configuraciones de la
impresora.
A continuación mostraremos un ejemplo de uso de estos diálogos mediante una
traducció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: [Link]
El ejemplo se compone de los siguientes archivos:
• Ventana.h
• [Link]
• [Link]
Los archivos Ventana.h y [Link] componen la clase Ventana, la cual representa la
ventana principal de la aplicación 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 diálogo estándar que nos permitirá obtener un dato del usuario. La segunda columna se
compone 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 siguiente
imagen.

A continuación explicamos el código del archivo [Link]:


1 #include "ventana.h"
2 #include <QPushButton>
3 #include <QLabel>
4 #include <QGridLayout>
5
6 #include <QInputDialog>
7 #include <QColorDialog>
8 #include <QFileDialog>
9 #include <QFontDialog>
10 #include <QMessageBox>
11 #include <QErrorMessage>
12
13 Ventana::Ventana(){
14 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 layout
con el que organizamos los componentes de nuestra ventana.
17 botonObtenerTexto = new QPushButton(trUtf8("Obtener Texto"));
18 botonObtenerEntero = new QPushButton(trUtf8("Obtener Entero"));
19 (...)
32 etiquetaObtenerTexto = new QLabel(trUtf8("\t\t\t\t"));
33 etiquetaObtenerEntero = new QLabel(trUtf8("\t\t\t\t"));
34 etiquetaObtenerDoble = new QLabel(trUtf8("\t\t\t\t"));
35 (...)
De las líneas 17 a 45 creamos los widgets que utilizaremos en el ejemplo. No mostramos
todas las líneas debido a que el código es muy repetitivo y las líneas son muy similares. En
dónde escribimos (…) van líneas iguales a las anteriores pero para los demás widgets. El
código del ejemplo se puede descargar mediante los links de la parte inferior de este
artículo.
A partir de la línea 17 creamos los botones que servirán para mostrar cada uno de los
diálogos estándar de Qt. A partir de la línea 32 y hasta la 45 creamos las etiquetas en las
que escribiremos el valor de retorno de cada uno de los diálogos.
47 etiquetaObtenerTexto->setFrameStyle(QFrame::Box);
48 etiquetaObtenerEntero->setFrameStyle(QFrame::Box);
49 etiquetaObtenerDoble->setFrameStyle(QFrame::Box);
50 (...)
62 layoutPrincipal->addWidget(botonObtenerTexto, 0, 0);
63 layoutPrincipal->addWidget(etiquetaObtenerTexto, 0, 1);
64 layoutPrincipal->addWidget(botonObtenerEntero, 1, 0);
65 (...)

connect(botonObtenerTexto, SIGNAL(clicked()), this,


SLOT(obtenerTexto()));
93
connect(botonObtenerEntero, SIGNAL(clicked()), this,
94
SLOT(obtenerEntero()));
95
connect(botonObtenerDoble, SIGNAL(clicked()), this,
96
SLOT(obtenerDoble()));
(...)
De las líneas 47 a 60 establecemos un marco para las etiquetas que mostrarán la respuesta
de los diálogos. En las líneas 62 a 89 configuramos la apariencia de la interfaz de usuario
utilizando un QGridLayout. Y finalmente, de las líneas 93 a 106 conectamos cada botón
con su slot correspondiente, cada slot mostrará un diálogo distinto para cada botón y
procesará la respuesta del usuario.
A partir de la línea 109 comienza la implementación de los slots, en todos ellos realizamos
las siguiente acciones:
1. Creamos una variable para almacenar la información que ingresa el
usuario 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 el
usuario.
3. Evaluamos el valor de respuesta del diálogo.
4. Dependiendo del valor de la respuesta decidimos de que manera
procesar 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 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 etiquetaObtenerEntero-
121 >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 línea 109 a la 115 implementamos el slot obtenerTexto, en él mostramos un diálogo
que nos permitirá obtener un valor de texto capturado por el usuario. Este diálogo lo
ejecutamos 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. Aqui
podemos establecer un valor de la enumeración EchoMode el cual
indicará si el texto debe ser visible, que no se muestre o que se
muestren 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ón
fue presionado.
• Las flags (banderas u opciones) del diálogo, las cuales establecen
propiedades del sistema de ventanas para un widget, como los botones
que se muestran en la barra de título o si debe mostrar barra de título o
no. 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 el
valor de la respuesta en la etiqueta correspondiente.
De la línea 117 a 122 implementamos el slot obtenerEntero, en él mostramos un diálogo
que 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 )
Los primeros tres y los dos últimos parámetros de está “familia” de funciones y de algunos
de los otros diálogos estándar son iguales, indican el widget padre, el título del diálogo, el
texto que se mostrará en el diálogo, un apuntador a la variable donde se almacenará la
respuesta 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 se
muestre 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 la
spinbox 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álogo
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 precisión. Este diálogo lo
ejecutamos mediante la función
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 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 de
uno.
De la línea 131 a 138 implementamos el slot obtenerElemento, en él mostramos un diálogo
que contiene una comobox que permite al usuario elegir un valor de una lista que
indiquemos. 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, bool
editable = 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 especifica
será cero
• Un valor booleano que indica si la combobox será editable
140 void Ventana::obtenerColor()
141 {
142 QColor color = QColorDialog::getColor();
143 if([Link]()) {
144 etiquetaObtenerColor->setText([Link]());
145 etiquetaObtenerColor->setPalette(QPalette(color));
146 etiquetaObtenerColor->setAutoFillBackground(true);
147 }
148 }
149
150 void Ventana::obtenerFuente()
151 {
152 QFont fuente = QFontDialog::getFont(&ok);
153 if(ok)
154 etiquetaObtenerFuente->setText([Link]());
155 }
De las líneas 140 a 148 implementamos el slot obtenerColor, en el mostramos un diálogo
que contiene controles especializados para permitir que el usuario eliga un color. Este
diálogo lo mostramos mediante la función
QColorDialog::getColor( const QColor & initial, QWidget * parent, const
QString & title, ColorDialogOptions options = 0 )
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á el
seleccionado
• El widget padre del diálogo
• El título del diálogo
• Miembros de la enumeración ColorDialogOptions, que permiten
establecer algunas propiedades del diálogo como mostrar canal alfa o
usar el diálogo nativo del sistema operativo
De la línea 150 a 155 implementamos el slot obtenerFuente, el cual muestra un diálogo que
incluye 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 valores
iniciales y configuraciones del diálogo similares a las de los diálogos anteriores pero en este
ejemplo utilizamos una función que sólo recibe como parámetros el apuntador a la variable
que almacena la respuesta que da el usuario al diálogo y un apuntador al widget padre de
este diálogo.
157 void Ventana::obtenerDirectorioExistente()
158 {
159 QString directorio = QFileDialog::getExistingDirectory(this,
160 trUtf8(""), etiquetaObtenerDirectorioExistente->text(),
161 QFileDialog::ShowDirsOnly);
162 if(![Link]())
163 etiquetaObtenerDirectorioExistente-
164 >setText(directorio);
165 }
166
167 void Ventana::obtenerArchivoAbrir()
168 {
169 QString filtroSeleccionado;
170 QString Nombre = QFileDialog::getOpenFileName(this,
171
172 trUtf8(""),
173
174 etiquetaObtenerArchivoAbrir->text(),
175
176 trUtf8("Todos los archivos (*);;Archivos de Cabecera C/C++
177 (*.h);;Archivos de Código Fuente C++ (*.cpp)"),
178
179 &filtroSeleccionado, 0);
180 if (![Link]())
181 etiquetaObtenerArchivoAbrir->setText(Nombre);
182 }
183
184 void Ventana::obtenerArchivosAbrir()
185 {
186 QStringList archivos = QFileDialog::getOpenFileNames(
187 this,
188
189 trUtf8(""),
190 "",
191
192 trUtf8("Todos los Archivos (*);;Archivos de Cabecera C/C++
193 (*.txt);;Archivos de Código Fuente C++ (*.cpp)"));
194
195 if ([Link]()) {
196 etiquetaObtenerArchivosAbrir-
197 >setText(QString("[%1]").arg([Link](", ")));
198 }
199 }

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 (![Link]())
etiquetaObtenerArchivoGuardar->setText(nombreArchivo);
}
De las líneas 157 a 207 implementamos los slots que hacen uso de las funciones estáticas
de 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 y
que nos permitirá seleccionar una carpeta o directorio. Este diálogo lo mostramos con la
funció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 permiten
configurar opciones del diálogo como el sólo mostrar directorios o
utilizar un diálogo no nativo
De la línea 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 diálogo utilizado en este slot con la función
QString QFileDialog::getOpenFileName ( QWidget * parent = 0, const
QString & caption = QString(), const QString & dir = QString(), const
QString & filter = QString(), QString * selectedFilter = 0, Options
options = 0 )
En esta función el último y los tres primeros parámetros son iguales al de la función del slot
anterior. Los parámetros propios de esta función son:
• Como cuarto parámetro, una cadena que representa los filtros que
podrán ser aplicados al diálogo, este filtro determina que tipo de archivo
se muestra. Para cada tipo de archivo se escribe una descripción y entre
paré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 seleccionado
actualmente.
De la línea 176 a la 187 implementamos el slot obtenerArchivosAbrir el cual muestra un
diálogo casi igual al del slot anterior con la diferencia de que este permite al usuario
seleccionar 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, Options
options = 0 )

Los parámetros de la función utilizada para ejecutar el diálogo son iguales a los de la
función utilizada para abrir un solo archivo.
De la línea 189 a 199 implementamos el slot obtenerArchivoGuardar el cual muestra un
diálogo que permite guardar un archivo al usuario y eligiendo su ubicación y especificando
su nombre. El diálogo utilizado en este slot lo ejecutamos mediante la función
QString QFileDialog::getSaveFileName ( QWidget * parent = 0, const
QString & caption = QString(), const QString & dir = QString(), const
QString & filter = QString(), QString * selectedFilter = 0, Options
options = 0 )
Los parámetros de esta función son iguales que los de la función utilizada para ejecutar el
diálogo que permite abrir archivos. Si especificamos un nombre que coincida con el de un
archivo existente se mostrará otro diálogo solicitando la confirmación del usuario, este
diálogo muestra dos botones de respuesta: Aceptar y Cancelar.
201 void Ventana::mostrarMensajeCritico()
202 {
203 QMessageBox::StandardButton respuesta = QMessageBox::critical(
204 this,
205 trUtf8(""),
206 trUtf8(""),
207 QMessageBox::Abort | QMessageBox::Retry |
208 QMessageBox::Ignore);
209
210 if (respuesta == QMessageBox::Abort)
211 etiquetaMostrarMensajeCritico->setText(tr("Abortar"));
212 else if (respuesta == QMessageBox::Retry)
213 etiquetaMostrarMensajeCritico-
214 >setText(tr("Reintentar"));
215 else
216 etiquetaMostrarMensajeCritico->setText(tr("Ignorar"));
217 }
218
219 void Ventana::mostrarMensajeInformacion()
220 {
221 QMessageBox::StandardButton respuesta;
222 respuesta = QMessageBox::information(this, trUtf8(""),
223 trUtf8("Este es un mensaje de información"));
224 if (respuesta == QMessageBox::Ok)
225 etiquetaMostrarMensajeInformacion->setText(tr("OK"));
226 else
227 etiquetaMostrarMensajeInformacion-
228 >setText(tr("Escape"));
229 }
230
231 void Ventana::mostrarMensajePregunta()
232 {
233 QMessageBox::StandardButton respuesta;
234 respuesta = QMessageBox::question(this, trUtf8(""),
235
236 trUtf8("Este es un mensaje con una pregunta"),
237
238 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
[Link](trUtf8("Guardar Otra Vez"),
248
QMessageBox::AcceptRole);
249
[Link](trUtf8("Continuar"),
250
QMessageBox::RejectRole);
251
if ([Link]() == QMessageBox::AcceptRole)
etiquetaMostrarMensajeAdvertencia->setText(tr("Guardar
Otra Vez"));
else
etiquetaMostrarMensajeAdvertencia-
>setText(tr("Continuar"));
}
A partir de la línea 201 y hasta el fin del archivo en la línea 251 implementamos los slots
que muestran los diálogos de la case QMessageBox. Entre las líneas 201 y 215
implementamos el slot mostrarMensajeCritico el cual permite mostrar un diálogo con un
icono de error que normalmente sirve para indicar que ocurrió algún error grave en la
aplicación. Mostramos este diálogo mediante la función
StandardButton QMessageBox::critical ( QWidget * parent, const QString &
title, const QString & text, StandardButtons buttons = Ok, StandardButton
defaultButton = NoButton )

Dicha función nos devuelve un valor de la enumeración StandarButttons, la cual contiene


todos los posibles valores que devuelve un diálogo 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 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
• El texto que deseamos mostrar en el diálogo
• Una lista de valores de la enumeración 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 botón
correspondiente
• Un valor de la enumeración StandarButtons el cual indica que botón se
establecerá como predeterminado, es decir sobre cual se hará un
efectro 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 cual
mostramos un diálogo que sirve para mostrar información al usuario, como un aviso sobre
la conclusión de una tarea o una notificación de algún evento. Mostramos el diálogo
utilizado 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 mostramos


un 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ón
StandardButton QMessageBox::question ( QWidget * parent, const QString &
title, const QString & text, StandardButtons buttons = Ok, StandardButton
defaultButton = NoButton )

Y finalmente de le la línea 241 a la 251 implementamos el slot mostrarMensajeAdvertencia


en 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 la
función
StandardButton QMessageBox::warning ( QWidget * parent, const QString &
title, const QString & text, StandardButtons buttons = Ok, StandardButton
defaultButton = NoButton )
Con esa función concluimos la revisión del código del archivo [Link]. En el archivo
[Link] 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 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


aplicación
En el artículo anterior de este tutorial vimos como implementar la funcionalidad de una
aplicación gráfica de Qt utilizando señales y slots. En este artículo revisaremos a detalle un
widget especial, QMainWindow, el cuál posee características 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 menús, los

cuales están compuestos por elementos de texto o etiquetas que indican


las acciones que puede realizar la aplicación y que se ejecutan al hacer
clic sobre ellas. Normalmente sólo existe una de ellas en la ventana y
está colocada en la parte superior, debajo de la barra de título. Algunos
ejemplos muy conocidos de menús que suelen colocarse en esta barra
son Archivo, Edición, Herramientas o Ayuda.
• Toolbars al igual que la barra de menús, esta clase de barras, conocida
como barra de herramientas está compuesta por las acciones que puede
realizar la aplicación, 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 menús y podemos
encontrar una o más 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 aplicación, las
acciones que está realizando o la descripción 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 aplicación 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 aplicación.
• Central Widget Este widget representa el área de trabajo de una
aplicación, como la tabla de celdas de una aplicación en hoja de cálculo
o 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 una


QMainWindow, la cual contendrá una etiqueta como widget central la cual cambiará el
texto que muestra dependiendo de la acción que ejecutemos, estas acciones se encontrarán
en una barra de menús y una barra de herramientas también incluiremos una barra de
estatus.
La aplicación 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 definición
de las funciones que utilizaremos en esta aplicación.
• [Link] es el archivo fuente de la clase
VentanaPrincipal, contiene la implementación de las funciones
declaradas en el archivo de encabezado.
• [Link]
A continuación revisaremos a detalle los archivos de la aplicación, sólo explicaremos las
secciones que no hayan sido revisadas en partes anteriores de este tutorial o que sean
relevantes en este contexto
ventanaprincipal.h
1 #ifndef VENTANAPRINCIPAL_H
2 #define VENTANAPRINCIPAL_H
3
4 #include <QMainWindow>
5
6 class QLabel;
7 class QToolBar;
8 class QAction;
9 class QMenu;
10
11 class VentanaPrincipal : public QMainWindow
12 {
13 Q_OBJECT
14
15 public:
16 VentanaPrincipal();
17
18 private slots:
19 void accionNuevoLanzada();
20 void accionAbrirLanzada();
21 void accionAcercaDeLanzada();
22 void accionSalirLanzada();
23
24 private:
25 QMenu* menuArchivo;
26 QMenu* menuAyuda;
27 QToolBar* barraDeHerramientas;
28 QAction* accionNuevo;
29 QAction* accionAbrir;
30 QAction* accionAcercaDe;
31 QAction* accionSalir;
32 QLabel* widgetCentral;
33 };
34 #endif
En la línea 4 incluimos el archivo de cabecera QMainWindow el cual contiene la definición
de la clase en la que basaremos nuestra ventana principal.
En la línea 11 definimos nuestra clase VentanaPrincipal e indicamos que heredará de
QMainWindow.
De la líneas 18 a 22 declaramos los slots por medio de los cuales implementaremos la
funcionalidad de nuestra aplicación.
Y finalmente de las líneas 24 a 32 declaramos las variables que utilizaremos en la
aplicación.
[Link]
1 #include "ventanaprincipal.h"
2
3 #include <QMenuBar>
4 #include <QToolBar>
5 #include <QLabel>
6 #include <QStatusBar>
7 #include <QMessageBox>
8
9 VentanaPrincipal::VentanaPrincipal()
10 {
11 menuArchivo = menuBar()->addMenu(trUtf8("&Archivo"));
12 menuAyuda = menuBar()->addMenu(trUtf8("A&yuda"));
13
14 barraDeHerramientas = addToolBar(trUtf8("&Archivo"));
15
16 widgetCentral = new QLabel(trUtf8("Widget central"));
17 widgetCentral->setFont(QFont("Sans-Serif", 25));
18
19 accionNuevo = new QAction(QIcon("iconos/[Link]"),
20 trUtf8("&Nuevo"), this);
21 accionNuevo->setShortcut(QKeySequence::New);
22 accionNuevo->setStatusTip(trUtf8("Crear un nuevo archivo"));
23
24 accionAbrir = new QAction(QIcon("iconos/[Link]"),
25 trUtf8("&Abrir"), this);
26 accionAbrir->setShortcut(QKeySequence::Open);
27 accionAbrir->setStatusTip(trUtf8("Abrir un archivo existente"));
28
29 accionSalir = new QAction(QIcon("iconos/[Link]"),
30 trUtf8("&Salir"), this);
31 accionSalir->setShortcut(QKeySequence::Quit);
32 accionSalir->setStatusTip(trUtf8("Salir de la aplicación"));
33
34 accionAcercaDe = new QAction(QIcon("iconos/[Link]"),
35 trUtf8("&Acerca de"), this);
36 accionAcercaDe->setShortcut(QKeySequence("Ctrl+d"));
37 accionAcercaDe->setStatusTip(trUtf8("Información sobre esta
38 aplicación"));
39
40 menuArchivo->addAction(accionNuevo);
41 menuArchivo->addAction(accionAbrir);
42 menuArchivo->addSeparator();
43 menuArchivo->addAction(accionSalir);
44
45 menuAyuda->addAction(accionAcercaDe);
46
47 barraDeHerramientas->addAction(accionNuevo);
48 barraDeHerramientas->addAction(accionAbrir);
49 barraDeHerramientas->addSeparator();
50 barraDeHerramientas->addAction(accionSalir);
51
52 setCentralWidget(widgetCentral);
53 statusBar()->showMessage(trUtf8("Bienvenido"));
54 setWindowTitle("Ventana Principal");
55 setMinimumSize(200, 200);
56
57 connect(accionNuevo, SIGNAL(triggered()),
58 this, SLOT(accionNuevoLanzada()));
59
60 connect(accionAbrir, SIGNAL(triggered()),
61 this, SLOT(accionAbrirLanzada()));
62
63 connect(accionAcercaDe, SIGNAL(triggered()),
64 this, SLOT(accionAcercaDeLanzada()));
65
66 connect(accionSalir, SIGNAL(triggered()),
67 this, SLOT(accionSalirLanzada()));
68 }
69
70 void VentanaPrincipal::accionNuevoLanzada()
71 {
72 widgetCentral->setText(trUtf8("Acción \"Nuevo\" lanzada"));
73 this->resize(QSize(widgetCentral->sizeHint().width(), 200));
74 }
75
76 void VentanaPrincipal::accionAbrirLanzada()
77 {
78 widgetCentral->setText(trUtf8("Acción \"Abrir\" lanzada"));
79 this->resize(QSize(widgetCentral->sizeHint().width(), 200));
80 }
void VentanaPrincipal::accionAcercaDeLanzada()
{
QMessageBox::about(this, this->windowTitle(), trUtf8("Aquí se debe
81 colocar información sobre la aplicación y la compañia que la
82 desarolla\n\nTutoriales, artículos y enlaces de programación
83 en:\n[Link]
84 }
85
void VentanaPrincipal::accionSalirLanzada()
{
exit(0);
}
De las líneas 1 a 7 incluimos los archivos de cabecera necesarios para implementar la
aplicació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 las
funciones
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 la
línea 12 realizamos lo mismo para el menú Ayuda.
En la línea 14 inicializamos la variable que representa a una barra de herramientas. La
función 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 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 la
aplicació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 y
que 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 el
constructor 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 que
se mostrará cuando la acción sea colocada dentro de una barra de herramientas y que a su
vez recibe como parámetro una cadena de texto con la dirección dónde se encuentra el
archivo de imágen que mostrará el icono, el segundo parámetro del constructor de la clase
QAction es una cadena que indica el texto que se mostrará cuando la acción sea colocada
dentro 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 una
representación abstracta de un comando de la aplicación 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 menús, un icono de
alguna barra de herramientas o una combinación de teclas, por mencionar algunos
ejemplos. 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 en
distintos lugares de la aplicación y de manera sincronizada, entonces podemos decir que
una QAction proporciona una interfaz común para la ejecución de los comandos de la
aplicación.
Siguiendo con el código, en la línea 20 establecemos un atajo de teclado para nuestra
acción Nuevo, mediante la función
QAction::setShortcut(const QKeySecuence secuencia)
la cual recibe como parámetro un elemento de la enumeración QKeySecuence, dicha
enumeración nos proporciona combinaciones estándar de teclas dependiendo de la
configuración 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
combinación de teclas Ctrl+N sin embargo esto puede ser distinto en otro sistema
operativo, pero al utilizar esta enumeración Qt se encargará de administrarlo y en caso de
que 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ón
correspondiente. 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 lo
hacemos 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 37
agregamos un separardor, utilizando la función
QMenu::addSeparator()
Un separador es una línea 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
categoría específica o diferente del resto de las acciones del mismo menú o barra de
herramientas.
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ón
utilizando 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
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, esto
lo realizamos mediante la función connect(), la cual revisamos a detalle en un artículo
anterior. 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 o
disparada) 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 una
combinació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 y
accionAbriLanzada cambiarán el texto que se muestra en la etiqueta utilizada como widget
central y redimensionarán la ventana para ajustarla al nuevo texto mostrado. El cambio de
texto 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 indicando
el ancho y alto del widget, respectivamente.
También utilizamos la función sizeHint() la cual devuelve un objeto QSize con el tamaño
requerido 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 la
línea 79 indicamos que al dispararse dicha acción se mostrará el conocido diálogo acerca de
el cuál contiene información sobre la aplicación como versióno fecha de lanzamiento y
sobre 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 la
lí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, sin
ningún error.
[Link]
1 #include "ventanaprincipal.h"
2 #include <QApplication>
3
4 int main(int argc, char* argv[])
5 {
6 QApplication app(argc, argv);
7
8 VentanaPrincipal* ventanaPrincipal = new VentanaPrincipal;
9
10 ventanaPrincipal->show();
11
12 return [Link]();
13 }
En la línea 1 incluimos el archivo de cabecera de la clase VentanaPrincipal, mientras que en
la línea 8 creamos e inicializamos un objeto de dicha clase, y finalmente en la línea 10
mostramos nuestra ventana principal.
Al ejecutar esta aplicación de ejemplo obtendremos algo parecido a lo mostrado en las
siguientes imagenes:
Es todo en este artículo, 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, 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 de
ejemplo, pero en él se pueden apreciar serias deficiencias, tal vez la más notoria es que sólo
es posible utilizar un elemento de interfaz gráfica (widget) a la vez, el cual en nuestro caso
fue 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, en
Qt 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ásico
de su uso.
QHBoxLayout
Nos permite ordenar los widgets en filas, es decir, de manera horizontal.
El código para crear una aplicación con un layout como el de la imagen anterior es el
siguiente, explicaremos sólo las líneas de código que no hayan sido vistas a detalle en
partes anteriores del tutorial:
1 #include <QObject>
2 #include <QApplication>
3 #include <QDialog>
4 #include <QHBoxLayout>
5 #include <QPushButton>
6
7 int main(int argc, char *argv[])
8 {
9 QApplication app(argc, argv);
10
11 QDialog *ventana = new QDialog();
12 QHBoxLayout *layout = new QHBoxLayout();
13 QPushButton *boton1 = new QPushButton(QObject::trUtf8("Botón 1"));
14 QPushButton *boton2 = new QPushButton(QObject::trUtf8("Botón 2"));
15 QPushButton *boton3 = new QPushButton(QObject::trUtf8("Botón 3"));
16
17 layout->addWidget(boton1);
18 layout->addWidget(boton2);
19 layout->addWidget(boton3);
20
21 ventana->setLayout(layout);
22 ventana->setWindowTitle("QHBoxLayout");
23 ventana->show();
24
25 return [Link]();
26 }
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, en
nuestro 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 en
lugar de una ventana principal buscando mantener la simplicidad del ejemplo. Un diálogo
es 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 como
una notificación al terminar un proceso o un error al realizarlo.
• Solicitar confirmación para realizar alguna acción como borrar o guardar
un archivo.
• Solicitar información, como la palabra a buscar en un diálogo de buscar
y reemplazar.
QHBoxLayout es una clase que representa a nuestro layout horizontal. QPushButton es una
clase que representa a un botón estándar.
11 QDialog *ventana = new QDialog();
12 QHBoxLayout *layout = new QHBoxLayout();
13 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 único
que recibe parámetros, este parámetro es una cadena de texto que contenga la etiqueta que
debe mostrar el botón. Las líneas 14 y 15 crean los otros botones de la misma forma.
17 layout->addWidget(boton1);
18 layout->addWidget(boton2);
19 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, un
entero que indica el indice de “flexibilidad” (stretch) del widget y un elemento de la
enumeración Qt::Alignment, los últimos dos parámetros pueden omitirse y en caso de
hacerlo se les asiga el valor de cero. El stretch indica la proporción de espacio disponible en
el layout que el widget ocupará, es relativo al stretch indicado en los otros widgets que
están dentro del layout, entre mayor sea el valor de stretch mayor será el espacio que
ocupará el widget. La enumeración Qt:Alignment indica la alineación 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 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 los
widgets podemos escribir las instrucciones en orden inverso o podemos indicar que
nuestros widgets se añadan de derecha a izquierda con la instrucción
setDirection(QBoxLayout:RightToLeft)
17 ventana->setLayout(layout);
18 ventana->setWindowTitle("QHBoxLayout");
En la línea 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 línea 18
indicamos el título 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 código para crear una aplicación con un layout como el de la imagen anterior es el
siguiente:
1 #include <QObject>
2 #include <QApplication>
3 #include <QDialog>
4 #include <QVBoxLayout>
5 #include <QPushButton>
6
7 int main(int argc, char *argv[])
8 {
9 QApplication app(argc, argv);
10
11 QDialog *ventana = new QDialog();
12 QVBoxLayout *layout = new QVBoxLayout();
13 QPushButton *boton1 = new QPushButton(QObject::trUtf8("Botón 1"));
14 QPushButton *boton2 = new QPushButton(QObject::trUtf8("Botón 2"));
15 QPushButton *boton3 = new QPushButton(QObject::trUtf8("Botón 3"));
16
17 layout->addWidget(boton1);
18 layout->addWidget(boton2);
19 layout->addWidget(boton3);
20
21 ventana->setLayout(layout);
22 ventana->setWindowTitle("QVBoxLayout");
23 ventana->show();
24
25 return [Link]();
26 }
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
instrucción
setDirection(QBoxLayout::BottomToTop);
QGridLayout
Nos permite ordenar los widgets a manera de tabla o rejilla.
El código para crear una aplicación con un layout similar al de la imagen es:
1 #include <QObject>
2 #include <QApplication>
3 #include <QDialog>
4 #include <QGridLayout>
5 #include <QPushButton>
6
7 int main(int argc, char *argv[])
8 {
9 QApplication app(argc, argv);
10
11 QDialog *ventana = new QDialog();
12 QGridLayout *layout = new QGridLayout();
13 QPushButton *boton1 = new QPushButton(QObject::trUtf8("Botón 1"));
14 QPushButton *boton2 = new QPushButton(QObject::trUtf8("Botón 2"));
15 QPushButton *boton3 = new QPushButton(QObject::trUtf8("Botón 3"));
16
17 layout->addWidget(boton1, 0, 0);
18 layout->addWidget(boton2, 0, 1);
19 layout->addWidget(boton3, 1, 0);
20
21 ventana->setLayout(layout);
22 ventana->setWindowTitle("QGridLayout");
23 ventana->show();
24
25 return [Link]();
26 }
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 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, dos
enteros que indican la fila y columna, respectivamente, de la celda sobre la cual queremos
agregar 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 esquina
superior izquierda tiene la posición fila=0, columna=0.
17 layout->addWidget(boton1, 0, 0);
18 layout->addWidget(boton2, 0, 1);
19 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 fila
cero con la columna cero, es decir, posición 0,0. Luego colocamos al boton2 y boton3 en
las celdas 0,1 y 1,0 respectivamente.
El espacio vacío en la celda 1,1 se genera debido a que el QGridLayout crea tantas
divisiones de filas y columnas como el número máximo 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 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 a
menos que establezcamos el alto/ancho mínimo 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 automáticamente el alto/ancho mínimo
de 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 las
funciones:
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 el
ejemplo anterior, pero al ejecutar el programa obtendríamos el mismo resultado que se
muestra en la imagen pasada. Esto ocurre debido a que aunque la fila y columna con el
número dos existen, estas tienen un alto y ancho de cero ya que no hemos colocado ningún
widget en ellas ni hemos establecido el tamaño mínimo para ellas. Pero si después de la
lí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:
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 código para crear una aplicación con un layout como el de la imagen anterior es el
siguiente:
1 #include <QObject>
2 #include <QApplication>
3 #include <QDialog>
4 #include <QFormLayout>
5 #include <QPushButton>
6
7 int main(int argc, char *argv[])
8 {
9 QApplication app(argc, argv);
10
11 QDialog *ventana = new QDialog();
12 QVBoxLayout *layout = new QVBoxLayout();
13 QPushButton *boton1 = new QPushButton(QObject::trUtf8("Botón 1"));
14 QPushButton *boton2 = new QPushButton(QObject::trUtf8("Botón 2"));
15 QPushButton *boton3 = new QPushButton(QObject::trUtf8("Botón 3"));
16
17 layout->addRow(QObject::trUtf8("Botón 1:"), boton1);
18 layout->addRow(QObject::trUtf8("Botón 2:"), boton2);
19 layout->addRow(QObject::trUtf8("Botón 3:"), boton3);
20
21 ventana->setLayout(layout);
22 ventana->setWindowTitle("QVBoxLayout");
23 ventana->show();
24
25 return [Link]();
26 }
En este caso nuestro layout será del tipo QFormLayout y para añadir widgets utilizarermos
la 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 layout->addRow(QObject::trUtf8("Botón 1:"), boton1);
18 layout->addRow(QObject::trUtf8("Botón 2:"), boton2);
19 layout->addRow(QObject::trUtf8("Botón 3:"), boton3);
En las líneas 17 a 19 agregamos los widgets al layout, utilizamos la versión sobrecargada
de 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 layout
es 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 de
indicar 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ás
complejas utilizamos layouts anidados, es decir, un layout dentro de otro. La función que
nos permite anidar layouts depende del tipo de layout que estemos utilizando, para
QHBoxLayout 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ónde
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 función 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á función recibe como parámetros 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 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.
1 #include <QApplication>
2 #include <QHBoxLayout>
3 #include <QVBoxLayout>
4 #include <QLabel>
5 #include <QLineEdit>
6 #include <QPushButton>
7 #include <QDialog>
8
9 int main(int argc, char *argv[])
10 {
11 QApplication app(argc, argv);
12
13 QDialog *ventana = new QDialog();
14 QHBoxLayout *layoutUsuario = new QHBoxLayout();
15 QHBoxLayout *layoutContrasenia = new QHBoxLayout();
16 QHBoxLayout *layoutBotones = new QHBoxLayout();
17 QVBoxLayout *layoutPrincipal = new QVBoxLayout();
18
19 QLabel *etiquetaUsuario = new QLabel("Usuario");
20 QLabel *etiquetaContrasenia = new QLabel("Password");
21
22 QLineEdit *campoUsuario = new QLineEdit();
23 QLineEdit *campoContrasenia = new QLineEdit();
24
25 QPushButton *botonAceptar = new QPushButton("Aceptar");
26 QPushButton *botonCancelar = new QPushButton("Cancelar");
27
28 layoutUsuario->addWidget(etiquetaUsuario);
29 layoutUsuario->addWidget(campoUsuario);
30
31 layoutContrasenia->addWidget(etiquetaContrasenia);
32 layoutContrasenia->addWidget(campoContrasenia);
33
34 layoutBotones->addStretch();
35 layoutBotones->addWidget(botonAceptar);
36 layoutBotones->addWidget(botonCancelar);
37
38 layoutPrincipal->addLayout(layoutUsuario);
39 layoutPrincipal->addLayout(layoutContrasenia);
40 layoutPrincipal->addLayout(layoutBotones);
41
42 ventana->setLayout(layoutPrincipal);
43
44 ventana->setWindowTitle(QObject::trUtf8("Iniciar Sesión"));
45 ventana->show();
46
47 return [Link]();
48 }
Al ejecutar este código obtendremos una salida parecida a la siguiente imagen
En las líneas 1 a 7 incluimos los archivos de cabecera necesarios para desarrollar la
aplicación, mientras que en las líneas 13 a 26 creamos los widgets que utilizaremos. En las
líneas 28 y 29 colocamos los widgets del campo usuario en un QHBoxLayout, lo mismo
hacemos para los campos de contraseña y para los botones. Con el fin de lograr una interfaz
má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 layoutPrincipal->addLayout(layoutUsuario);
39 layoutPrincipal->addLayout(layoutContrasenia);
40 layoutPrincipal->addLayout(layoutBotones);
41
42 ventana->setLayout(layoutPrincipal);
A partir de la línea 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
contraseña y por último el que contiene los botones y finalmente en la línea 40
establecemos el layout principal de nuestra apliciación.
Es posible diseñar una interfaz de usuario utilizando distintas combinaciones de layouts, es
cuestión de tiempo y experiencia poder encontrar aquella que sea más fácil y rápida de
crear 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 lograrse
utilizando un QFormLayout en lugar de los primeros dos QHBoxLayout. El código es el
siguiente:
1 #include <QApplication>
2 #include <QHBoxLayout>
3 #include <QFormLayout>
4 #include <QLineEdit>
5 #include <QPushButton>
6 #include <QDialog>
7
8 int main(int argc, char *argv[])
9 {
10 QApplication app(argc, argv);
11
12 QDialog *ventana = new QDialog();
13 QHBoxLayout *layoutBotones = new QHBoxLayout();
14 QFormLayout *layoutPrincipal = new QFormLayout();
15
16 QLineEdit *campoUsuario = new QLineEdit();
17 QLineEdit *campoContrasenia = new QLineEdit();
18
19 QPushButton *botonAceptar = new QPushButton("Aceptar");
20 QPushButton *botonCancelar = new QPushButton("Cancelar");
21
22 layoutBotones->addStretch();
23 layoutBotones->addWidget(botonAceptar);
24 layoutBotones->addWidget(botonCancelar);
25
26 layoutPrincipal->addRow(QString("Usuario"), campoUsuario);
27 layoutPrincipal->addRow(QString("Password"), campoContrasenia);
28 layoutPrincipal->addRow(layoutBotones);
29
30 ventana->setLayout(layoutPrincipal);
31
32 ventana->setWindowTitle(QObject::trUtf8("Iniciar Sesión"));
33 ventana->setWindowFlags(Qt::Window);
34 ventana->show();
35
36 return [Link]();
37 }
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ón
incluso 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 de
có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 interfaz
gráfica 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 distribución (O la ruta escénica)
El primer paso es conseguir el paquete de distribución de la página [Link] de la
sección 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+-[Link]
tar xvfj gtk+-[Link].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 dinámicas 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 fácil
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+.

También podría gustarte