Gtk.Dialog: Ventanas de Dialogo Modales
Uno de los temas que a mi forma de ver es de suma
importancia al trabajar con Gtk#
y MonoDevelop,
es el uso y manejo de
Ventanas de Diálogo de forma Modal. En este
artículo trabajaré en crear una solicitud de
"Login" de una supuesta aplicación, donde se
pedirá el nombre de usuario y contraseña en un
formulario "Gtk.Dialog", solicitada por un formulario principal
"Gtk.Window", se recuperarán los datos del dialogo y se
mostrarán en el Formulario Principal.Para lograr crear la aplicación, vamos a necesitar generar un nuevo proyecto, así que como siempre, abrimos MonoDevelop (en este artículo se esta usando la versión 0.12) y vamos al menú "Archivo" para luego pulsar sobre "Nuevo Proyecto...", seleccionamos un "Proyecto Gtk# 2.0" y le damos de nombre "DialogoLogin"
MonoDevelop creará todos los archivos de inicio necesarios, sin embargo para este proyecto en particular, es necesario agregar una nueva subclase de ventana de dialogo "Gtk.Dialog" la cual se puede crear fácilmente dando click con el botón derecho del ratón sobre "Interfaz de Usuario" en la ventana de "solución". De esta forma aparecerá un menú desde donde vamos a seleccionar la opción "Nuevo Diálogo..."
Inmediatamente nos aparecerá una ventana pidiéndonos el nombre del archivo, al cual yo llamé "Login".
Ahora ya tenemos los dos componentes principales de los que se compone este proyecto: El "MainWindow" (Gtk.Window) que es nuestra ventana principal y "DialogoLogin.Login" (Gtk.Dialog) que es nuestro Formulario de Login.
Ahora debemos de darle forma a nuestros formularios, para ello usaremos el fantástico Stetic ya incluido en MonoDevelop. Quiero que el ejemplo sea sumamente sencillo, así que a nuestro "MainWindow" le vamos a agregar únicamente un "label" que ocupara toda la ventana, y sus propiedades son las siguientes:
Label en MainWindow:
Nombre del Widget: "MensajeSalida"
Etiqueta: "Esperando Login"
Hay que recordar pulsar el botón "Bind to Field" para que se declare el widget label en el código fuente de su clase, ya que más adelante lo usaremos.
La ventana debería de quedar más o menos así:
Ahora vamos a diseñar el diálogo, pero antes hay que entender algunos conceptos propios de un "Gtk.Dialog".
Primero que nada, es importante leer la documentación (algo escueta) que nos proporciona el Proyecto Mono para este tipo de Ventana, la cual es accesible en Gtk.Dialog.
Una ventana de dialogo Gtk# es simplemente una "subclase" de captura o selección de datos, formado por dos partes importantes, el área de diseño de formulario, y el área de acción.
El área de acción por lo general son uno o más botones alineados a la derecha, y cada botón regresa una señal de tipo "ResponseType" (una enumeración) la cual deberá ser evaluada por la clase padre (en este caso MainWindow), donde se podrá adquirir la información capturada en el diálogo.
Para ayudar al diseño del diálogo he preparado un video, pulsa sobre la siguiente imagen para verlo en acción:
Las propiedades de cada control son las siguientes:
Button 1
Nombre del Widget: buttonAceptar
Button Type: Stock Button
Stock Item: gtk-ok
Response Id: OK
Button 2
Nombre del Widget: buttonCancelar
Button Type: Stock Button
Stock Item: gtk-cancel
Response Id: Cancel
Label 1
Etiqueta: "Usuario:"
Label 2
Etiqueta: "Contraseña:"
Entry 1
Nombre del Widget: entryUser
Entry 2
Nombre del Widget: entryPass
Visibilidad: (Desactivado)
Después debemos seleccionar el widget "entryUser" y pulsar sobre el botón "Bind to Field" y hacemos lo mismo con "entryPass", para declarar estos dos widgets en nuestro código fuente, el cual nos debería quedar de la siguiente forma:
using System; namespace DialogoLogin { public class Login : Gtk.Dialog { protected Gtk.Entry entryUser; protected Gtk.Entry entryPass; public Login() { Stetic.Gui.Build(this, typeof(DialogoLogin.Login)); } } }
Ahora debemos de idear la forma de adquirir la información capturada en el diálogo, lo cual es muy fácil creando una propiedad por cada "entry".
public string User { get { return entryUser.Text; } } public string Pass { get { return entryPass.Text; } }
Ya con esto terminamos con el diálogo y viene lo interesante, que es ejecutar el diálogo y capturar los datos introducidos en el. Esto se logra fácilmente desde el constructor de la clase principal
public MainWindow (): base ("") { Stetic.Gui.Build (this, typeof(MainWindow)); DialogoLogin.Login MyDialog = new DialogoLogin.Login(); MyDialog.Show(); ResponseType MyResponse = (ResponseType)MyDialog.Run(); if (MyResponse == ResponseType.Ok){ MensajeSalida.Text = "El usuario capturado fué: "; MensajeSalida.Text += MyDialog.User; MensajeSalida.Text += "\nLa contraseña fué: "; MensajeSalida.Text += MyDialog.Pass; } else { MensajeSalida.Text = "La respuesta fué: "; MensajeSalida.Text += MyResponse.ToString(); } MyDialog.Destroy(); }
Desde la linea 5 veremos que se declara el objeto llamado MyDialog, después se muestra el diálogo, se declara una variable de respuesta y se corre el diálogo. El
MyDialog.Run() es un loop que no
terminará hasta adquirir
una respuesta (ResponseType), esto quiere decir que se
cerrará al pulsar sobre algún botón
del "área de acción" o se cierre la ventana por
otro medio, por lo que a continuación se evalúa
si se pulso sobre "Aceptar" (Ok) o si se recibió alguna otra
respuesta. En caso de que la respuesta fuera "Aceptar" entonces
adquirimos los valores escritos por medio de las propiedades antes
programadas en la clase del diálogo, para por fin escribir
en nuestro label llamado "MensajeSalida".
Todos los archivos y código usados en este artículo se encuentran listos para su descarga a continuación.
| Adjunto | Tamaño |
|---|---|
| DialogoLogin.tar.gz | 6.64 KB |
![]() |
¡Excelente serie de artículos! Me han vuelto a conectar con el mundo de la programación en GNU/Linux. |
![]() |
En la versión de MonoDevelop que usas ya no es necesario ni existe ese botón: Nota Mental: Debo actualizar los artículos Saludos |



Tengo la necesidad que el Dialog obtenga el GrabFocus ya que al ocuparlo sobre otra forma no aparece con el Focus, pero ademas lo necesito hacer dentro del Constructor del Dialog para que posteriormente ejecute la propiedad Run, como sigue: