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.
- ventanaprincipal.cpp es el archivo fuente de la clase VentanaPrincipal, contiene la implementación de las funciones declaradas en el archivo de encabezado.
- main.cpp
A continuación revisaremos a detalle los archivos de la aplicación, sólo explicaremos 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 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | #ifndef VENTANAPRINCIPAL_H #define VENTANAPRINCIPAL_H #include <QMainWindow> class QLabel; class QToolBar; class QAction; class QMenu; class VentanaPrincipal : public QMainWindow { Q_OBJECT public: VentanaPrincipal(); private slots: void accionNuevoLanzada(); void accionAbrirLanzada(); void accionAcercaDeLanzada(); void accionSalirLanzada(); private: QMenu* menuArchivo; QMenu* menuAyuda; QToolBar* barraDeHerramientas; QAction* accionNuevo; QAction* accionAbrir; QAction* accionAcercaDe; QAction* accionSalir; QLabel* widgetCentral; }; #endif |
En la línea 4 incluimos el archivo de cabecera QMainWindow el cual contiene la definició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.
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 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 81 82 83 84 85 | #include "ventanaprincipal.h" #include <QMenuBar> #include <QToolBar> #include <QLabel> #include <QStatusBar> #include <QMessageBox> VentanaPrincipal::VentanaPrincipal() { menuArchivo = menuBar()->addMenu(trUtf8("&Archivo")); menuAyuda = menuBar()->addMenu(trUtf8("A&yuda")); barraDeHerramientas = addToolBar(trUtf8("&Archivo")); widgetCentral = new QLabel(trUtf8("Widget central")); widgetCentral->setFont(QFont("Sans-Serif", 25)); accionNuevo = new QAction(QIcon("iconos/nuevo.png"), trUtf8("&Nuevo"), this); accionNuevo->setShortcut(QKeySequence::New); accionNuevo->setStatusTip(trUtf8("Crear un nuevo archivo")); accionAbrir = new QAction(QIcon("iconos/abrir.png"), trUtf8("&Abrir"), this); accionAbrir->setShortcut(QKeySequence::Open); accionAbrir->setStatusTip(trUtf8("Abrir un archivo existente")); accionSalir = new QAction(QIcon("iconos/salir.png"), trUtf8("&Salir"), this); accionSalir->setShortcut(QKeySequence::Quit); accionSalir->setStatusTip(trUtf8("Salir de la aplicación")); accionAcercaDe = new QAction(QIcon("iconos/salir.png"), trUtf8("&Acerca de"), this); accionAcercaDe->setShortcut(QKeySequence("Ctrl+d")); accionAcercaDe->setStatusTip(trUtf8("Información sobre esta aplicación")); menuArchivo->addAction(accionNuevo); menuArchivo->addAction(accionAbrir); menuArchivo->addSeparator(); menuArchivo->addAction(accionSalir); menuAyuda->addAction(accionAcercaDe); barraDeHerramientas->addAction(accionNuevo); barraDeHerramientas->addAction(accionAbrir); barraDeHerramientas->addSeparator(); barraDeHerramientas->addAction(accionSalir); setCentralWidget(widgetCentral); statusBar()->showMessage(trUtf8("Bienvenido")); setWindowTitle("Ventana Principal"); setMinimumSize(200, 200); connect(accionNuevo, SIGNAL(triggered()), this, SLOT(accionNuevoLanzada())); connect(accionAbrir, SIGNAL(triggered()), this, SLOT(accionAbrirLanzada())); connect(accionAcercaDe, SIGNAL(triggered()), this, SLOT(accionAcercaDeLanzada())); connect(accionSalir, SIGNAL(triggered()), this, SLOT(accionSalirLanzada())); } void VentanaPrincipal::accionNuevoLanzada() { widgetCentral->setText(trUtf8("Acción \"Nuevo\" lanzada")); this->resize(QSize(widgetCentral->sizeHint().width(), 200)); } void VentanaPrincipal::accionAbrirLanzada() { widgetCentral->setText(trUtf8("Acción \"Abrir\" lanzada")); this->resize(QSize(widgetCentral->sizeHint().width(), 200)); } void VentanaPrincipal::accionAcercaDeLanzada() { QMessageBox::about(this, this->windowTitle(), trUtf8("Aquí se debe colocar información sobre la aplicación y la compañia que la desarolla\n\nTutoriales, artículos y enlaces de programación en:\nhttp://www.programacion-linux.com")); } 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.
main.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 | #include "ventanaprincipal.h" #include <QApplication> int main(int argc, char* argv[]) { QApplication app(argc, argv); VentanaPrincipal* ventanaPrincipal = new VentanaPrincipal; ventanaPrincipal->show(); return app.exec(); } |
En la línea 1 incluimos el archivo de cabecera de la clase VentanaPrincipal, mientras que 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.
Artículos relacionados
- Tutorial de Qt4: Diálogos, comunicación con el usuario (Parte II)
- Tutorial de Qt4: Diálogos, comunicación con el usuario (Parte I)
- Tutorial Gtk+ 2: Instalacion de Gtk+ 2 en Linux
- Tutorial Gtk+2: Hola Mundo
- Tutorial de Qt 4: Instalación de Qt 4.5 en Ubuntu












Muro de Comentarios RSS Feed
[...] Puedes continuar con el tutorial de Qt 4 en el artículo QMainWindow, la ventana principal de la aplicación. [...]
[...] el artículo anterior de este tutorial revisamos a detalle el widget QMainWindow el cuál nos sirve para crear la ventana principal de nuestra aplicación. En este artículo [...]