Tutorial de Qt4: Diálogos, comunicación con el usuario (Parte I)

PésimoMaloRegularBuenoExcelente (No Ratings Yet)
Loading ... Loading ...

En 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 hablaremos acerca de los diálogos, pequeñas ventanas secundarias que sirven para comunicarse con el usuario.

Los diálogos son útiles en ocasiones en las que requerimos la confirmación del usuario antes de ejecutar una acción, como al guardar o eliminar un archivo o al salir de una aplicación, también suelen utilizarse para obtener pequeñas cantidades de información, como la palabra a buscar en un diálogo de buscar y reemplazar o el nombre que se desea dar a un marcador/favorito en un navegador web.

Podemos utilizar diálogos de Qt de dos formas distintas, una es creándolos nosotros como lo hemos hecho en otros artículos de este tutorial y la otra es utilizar el API estática de diálogos comúnmente utilizados que nos provee Qt, entre estos diálogos se encuentran los de petición de información al usuario o los de selección de carpetas, archivos, fuentes o colores.

Al especificar el widget padre para un QDialog, la posición por defecto será en el centro y encima del widget padre. También compartirá la entrada del padre en la barra de tareas del sistema operativo.

Podemos mostrar un diálogo en pantalla con una de las siguientes dos funciones:

void QWidget::show();

Esta función se hereda de QWidget y es equivalente a llamar a la función setVisible con un parámetro booleano con valor de  true, mostrar un diálogo a través de esta función es útil si queremos que el usuario pueda continuar interactuando con la ventana que mostró el diálogo, los diálogos que permiten dicha interacción se conocen con el nombre de diálogos no modales.

int QDialog::exec();

Esta función sirve para mostrar un diálogo modal, este es un tipo de diálogos que bloquean el acceso a las demás ventanas de la aplicación. Mostrar un diálogo con la función exec() permite obtener el valor de la respuesta elegida por el usuario. A continuación mostramos un ejemplo para observar de mejor manera la diferencia entre show y exec. El ejemplo se compone de los siguientes archivos:

  • DialogoModal.h
  • DialogoModal.cpp
  • Ventana.h
  • Ventana.cpp
  • main.cpp

La clase DialogoModal, representa un diálogo personalizado muy simple que sólo muestra una etiqueta en el lugar en dónde se colocarían los widgets en un diálogo de una aplicación real, está clase nos servirá para ver cómo podemos gestionar las respuestas que puede emitir un diálogo modal.

El código del archivo DialogoModal.cpp es el siguiente:

NOTA: Sólo explicaremos las líneas relevantes para el ejemplo o que no hayan sido explicadas en artículos anteriores de este tutorial.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include "dialogomodal.h"
 
#include <QPushButton>
#include <QLabel>
#include <QVBoxLayout>
#include <QHBoxLayout>
 
DialogoModal::DialogoModal()
{
	QVBoxLayout* layoutPrincipal = new QVBoxLayout;
	QHBoxLayout* layoutBotones = new QHBoxLayout;
 
	nombre = new QLabel(trUtf8("Diálogo Modal"));
	botonAceptar = new QPushButton(trUtf8("Aceptar"));
	botonRechazar = new QPushButton(trUtf8("Rechazar"));
	botonOtro = new QPushButton(trUtf8("Otro"));
 
	nombre->setFont(QFont("Sans-Serif", 15));
 
	layoutBotones->addStretch();
	layoutBotones->addWidget(botonAceptar);
	layoutBotones->addWidget(botonRechazar);
	layoutBotones->addWidget(botonOtro);
 
	layoutPrincipal->addWidget(nombre);
	layoutPrincipal->addLayout(layoutBotones);
 
	setLayout(layoutPrincipal);
 
	connect(botonAceptar, SIGNAL(clicked()), this, SLOT(accept()));
	connect(botonRechazar, SIGNAL(clicked()), this, SLOT(reject()));
	connect(botonOtro, SIGNAL(clicked()), this, SLOT(botonOtroPresionado()));
}
 
void DialogoModal::botonOtroPresionado() {
	done(99);
}

De la línea 14 a la 16 creamos los widgets que componen nuestro diálogo. Los botones botonAceptar, botonRechazar y botonOtro representan las distintas opciones con las que el usuario puede responder al mensaje (o lo que le mostremos) en el diálogo.

De las líneas 30 a 32 conectamos la señal clicked() de los botones al slot correspondiente con la acción que queremos que realicen. Los botones botonAceptar y botonRechazar se conectan a los slots accept() y reject(), los cuáles están previamente definidos en QDialog y se encargan de ocultar el diálogo y devolver el código respuesta correspondiente, 1 para accept (aceptar) y 0 para reject (rechazar), como valor de retorno de la función exec.

Por otra parte el botón de nombre botonOtro se conecta a un slot botonOtroPresionado el cuál es implementado por nosotros. Dicha implementación comienza en la línea 35 y en realidad es sólo una “envoltura” para llamar al slot:

QDialog::done(int r)

El cuál también es parte de QDialog, este slot nos permite hacer algo similar a accept() y reject(), es decir, ocultar el diálogo y enviar un código de respuesta, con la diferencia de que en done() podemos especificar el código de respuesta que queremos enviar. En este caso enviamos el número 99, pero puede ser cualquier otro entero. El código del archivo Ventana.cpp es el siguiente:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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
#include "ventana.h"
 
#include <QHBoxLayout>
#include <QPushButton>
#include <QLabel>
#include <QApplication>
#include <QMessageBox>
 
Ventana::Ventana()
{
	QGridLayout* layoutPrincipal = new QGridLayout;
 
	botonDialogoModal = new QPushButton(QObject::trUtf8("Mostrar Diálogo Modal"));
	botonDialogoNoModal = new QPushButton(QObject::trUtf8("Mostrar Diálogo No Modal"));
 
	resultadoDialogoModal = new QLabel("\t\t");
 
	dialogoModal = new DialogoModal;
	dialogoNoModal = new QDialog(this);
 
	resultadoDialogoModal->setFrameStyle(1);
 
	layoutPrincipal->addWidget(botonDialogoModal, 0, 0);
	layoutPrincipal->addWidget(resultadoDialogoModal, 0, 1);
	layoutPrincipal->addWidget(botonDialogoNoModal, 1, 0);
 
	setLayout(layoutPrincipal);
	setWindowFlags(Qt::Window);
	setWindowTitle(trUtf8("Diálogos Personalizados - http://programacion-linux.com/"));
 
	connect(botonDialogoModal, SIGNAL(clicked()), this, SLOT(ejecutar()));
	connect(botonDialogoNoModal, SIGNAL(clicked()), dialogoNoModal, SLOT(show()));
	connect(this, SIGNAL(rejected()), this, SLOT(salir()));
}
 
void Ventana::salir() {
	QApplication::exit(0);
}
 
void Ventana::ejecutar() {
	int respuesta = dialogoModal->exec();
 
	QMessageBox::information(this, "", QString::number(respuesta));
 
	switch(respuesta) {
	case 0:
		resultadoDialogoModal->setText(trUtf8("Rechazar presionado"));
		break;
 
	case 1:
		resultadoDialogoModal->setText(trUtf8("Aceptar presionado"));
		break;
 
	default:
		resultadoDialogoModal->setText(trUtf8("Otro presionado"));
		break;
	}
}

De las líneas 15 a 21 creamos los widgets que componen nuestra ventana. En la línea 18 creamos una etiqueta que mostrará la respuesta de nuestro diálogo modal y le indicamos que muestre dos tabuladores como texto para que tenga un tamaño mínimo que pueda contener la respuesta del diálogo, esto es sólo por motivos estéticos.

En la línea 21 creamos un diálogo que utilizaremos como diálogo no modal e indicamos que nuestra clase ventana será su padre, esto provocará que el diálogo no modal se muestre centrado respecto a la posición de nuestra ventana; Este comportamiento no lo observamos para nuestro diálogo modal porque no hemos establecido un padre para él.

En la línea 23 establecemos un estilo de línea para el borde/marco de la etiqueta que mostrará la respuesta del diálogo modal. De las líneas 33 a 35 realizamos las conexiones de señales y slots. En la línea 35 conectamos la señal, rejected() de nuestra ventana al slot salir, el cual es implementado por nostros y que sólo es una “envoltura” para la función QApplication::exit() que hará que termine nuestra aplicación. La señal rejected() también se emite cuándo se usa el boton cerrar de la barra de título de un diálogo. En las líneas 33 y 34 conectamos la señal clicked de los botones a los slots que mostrarán el diálogo correspondiente, modal o no modal, el diálogo no modal lo mostramos llamando directamente a show debido a que esta función no devuelve ningún código de respuesta que tengamos que gestionar.

El diálogo modal lo mostramos en el slot ejecutar(), implementado por nosotros en la línea 42  y asignamos su resultado a una variable, después procesamos el valor de este resultado, en este caso comparamos dicho valor con los códigos de resultado usuales y el que definimos nosotros, dependiendo de con que valor coincida modificamos el valor de la eitqueta resultadoDialogoModal.

Es todo en la primera parte de este artículo, en la siguiente parte continuaremos con el tema de los diálogos; Mostraremos la otra forma de obtener información de parte del usuario: Utilizando los diálogos estándar de Qt.




Artículos relacionados

Autor plugin: nessus

Share this post

  • Digg
  • Del.icio.us
  • StumbleUpon
  • Reddit

One Comment to “Tutorial de Qt4: Diálogos, comunicación con el usuario (Parte I)”

  1. [...] el artículo anterior revisamos la primera de las dos formas principales de utilizar diálogos en Qt, esto es creando [...]

Leave a Reply