Recientemente necesitaba validar un “Entry” en gtk-sharp para que el usuario sólo pudiera capturar números. Nunca antes había programado en Mono y tampoco había desarrollado interfaces gráficas usando Gtk o Gtk#, asi que probablemente este post le sea útil únicamente a novatos en Mono y Gtk# ( como yo :) ).
Buscando en internet encontré 2 posts, de los cuales tome código y le hice pequeñas adecuaciones para crear 2 clases que son subclases de la clase Entry.
Lo que hace el código es capturar el evento KeyPress y verificar la tecla que pulsó el usuario, a partir de ahi decide si es una tecla o caracter permitido o no.
Creé una clase llamada EntryEnteros y una clase llamada EntryDecimales. Las clases son casí idénticas, la diferencia es que la segunda acepta el punto como caracter permitido y la primera no. Esto implica que en la segunda clase se agrega el caracter “.” en la cadena s_charvalidos pero también se captura cuando el usuario pulsa el punto del teclado numérico (Gdk.Key.KP_Decimal).
El código del post http://nexus.developarts.com/limitar_la_captura_de_un_entry#comment-769 no funciona si el usuario usa el teclado numérico para introducir datos, sólo acepta los números de la parte superior del teclado; tampoco permite al usuario moverse con las flechas izquierda o derecha. El código que me sirvió de base para incluir eso está en el post http://mbrenes.blogspot.com/2007_02_01_archive.html pero es para Gtk, así que sólo hice los cambios necesarios para pasarlo a Gtk#.
Este ejemplo fue realizado en Debian Lenny
Esta es la clase EntryEnteros
/* Archivo entryenteros.cs */
using System;
using Gtk;
public class EntryEnteros : Entry
{
public EntryEnteros()
{
KeyPressEvent += new KeyPressEventHandler(TeclaPulsada);
}
// Conectamos el manejador de eventos antes del evento KeyPress
[GLib.ConnectBefore ()]
private void TeclaPulsada(object o, KeyPressEventArgs args)
{
string s_charvalidos = "0123456789";
// Para que al pulsar enter el foco se pase al siguiente control
if (args.Event.Key == Gdk.Key.Return || args.Event.Key == Gdk.Key.KP_Enter)
{
Toplevel.ChildFocus (DirectionType.TabForward);
args.RetVal = true;
}
else
// Solo se permiten los caracteres en s_charvalidos, los números del teclado numérico (KP_0...),
// el backspace, el delete, flecha izquierda, flecha derecha
if (Array.IndexOf(s_charvalidos.ToCharArray(), Convert.ToChar(args.Event.Key)) == -1 && args.Event.Key!=Gdk.Key.BackSpace && args.Event.Key!=Gdk.Key.Delete && args.Event.Key!=Gdk.Key.Left && args.Event.Key!=Gdk.Key.Right && !(args.Event.Key >=Gdk.Key.KP_0 && args.Event.Key <=Gdk.Key.KP_9))
args.RetVal = true;
}
}
Esta es la clase EntryDecimales
/* Archivo entrydecimales.cs */
using System;
using Gtk;
public class EntryDecimales : Entry
{
public EntryDecimales()
{
KeyPressEvent += new KeyPressEventHandler(TeclaPulsada);
}
// Conectamos el manejador de eventos antes del evento KeyPress
[GLib.ConnectBefore ()]
private void TeclaPulsada(object o, KeyPressEventArgs args)
{
string s_charvalidos = "0123456789.";
// Para que al pulsar enter el foco se pase al siguiente control
if (args.Event.Key == Gdk.Key.Return || args.Event.Key == Gdk.Key.KP_Enter)
{
Toplevel.ChildFocus (DirectionType.TabForward);
args.RetVal = true;
}
else
// Solo se permiten los caracteres en s_charvalidos, los números del teclado numérico (KP_0...),
// el backspace, el delete, flecha izquierda, flecha derecha
if (Array.IndexOf(s_charvalidos.ToCharArray(), Convert.ToChar(args.Event.Key)) == -1 && args.Event.Key!=Gdk.Key.BackSpace && args.Event.Key!=Gdk.Key.Delete && args.Event.Key!=Gdk.Key.Left && args.Event.Key!=Gdk.Key.Right && args.Event.Key!=Gdk.Key.KP_Decimal && !(args.Event.Key >=Gdk.Key.KP_0 && args.Event.Key <=Gdk.Key.KP_9))
args.RetVal = true;
}
}
Con el siguiente programa podemos probar nuestras 2 clases
/* Archivo prueba.cs */
using System;
using Gtk;
public class prueba
{
public static void Main()
{
Application.Init();
Window w_principal = new Window("Limitar captura en un Entry");
w_principal.DeleteEvent += delete_event;
EntryEnteros e_cantidad = new EntryEnteros ();
EntryDecimales e_precio = new EntryDecimales ();
HBox hb_cantidad = new HBox (true, 0);
HBox hb_precio = new HBox (true, 0);
VBox vb_contenedor = new VBox();
hb_cantidad.PackStart (new Label ("Cantidad: "), false, false, 0);
hb_cantidad.PackStart (e_cantidad);
hb_precio.PackStart (new Label ("Precio: "), false, false, 0);
hb_precio.PackStart (e_precio);
vb_contenedor.PackStart (hb_cantidad, true, true, 0);
vb_contenedor.PackStart (hb_precio, true, true, 0);
w_principal.Add(vb_contenedor);
w_principal.ShowAll();
Application.Run();
}
static void delete_event (object obj, DeleteEventArgs args)
{
Application.Quit();
}
}
Compilamos
gmcs -pkg:gtk-sharp-2.0 prueba.cs entryenteros.cs entrydecimales.cs
Con esto tenemos nuestro archivo prueba.exe, el cual ejecutamos tecleando ./prueba.exe
A continuación una captura de la pantalla ya con datos introducidos
![]()
Etiquetas: Capturar sólo números, Entry Gtk#, Mono
Junio 15, 2009 a las 8:04 am |
muy buena tu clases pero no he podido hacer que cuando presione la tecla ENTER cambie el foco a otro control. agradecería la ayuda. gracias
Junio 15, 2009 a las 12:40 pm |
Hola rodrigo
Ya he modificado las clases entryenteros y entrydecimales para que al pulsar Enter el foco se vaya al siguiente control.
Espero sea lo que necesitabas.
Saludos