¿Es posible limitar TextCtrl para aceptar números solo en wxPython?
Pregunta
Quiero tener un control de texto que solo acepte números.(Solo valores enteros como 45 o 366)
¿Cuál es la mejor manera de hacer esto?
Solución
IntCtrl
, Masked Edit Control
y NumCtrl
están diseñados para hacer precisamente esto, con diferentes niveles de control. Pedido de la demo wx en "Más ventanas / controles" para ver cómo funcionan.
(O, si usted está en su lugar con muchas ganas de hacer esto directamente con un TextCtrl prima, creo que te quiere coger eventos EVT_CHAR, probar los personajes, y llamar a evt.Skip () si se permitió una personaje.)
Otros consejos
que tenía que hacer algo similar, la comprobación de los códigos alfanuméricos. La punta de EVT_CHAR era lo correcto:
class TestPanel(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent, -1)
self.entry = wx.TextCtrl(self, -1)
self.entry.Bind(wx.EVT_CHAR, self.handle_keypress)
def handle_keypress(self, event):
keycode = event.GetKeyCode()
if keycode < 255:
# valid ASCII
if chr(keycode).isalnum():
# Valid alphanumeric character
event.Skip()
Puede intentar IntCtrl
, EVT_CHAR
, o implementar un nuevo validador / existente (como IntValidator ). Los validadores se pueden utilizar para validar un campo (útil cuando se trata de validar varias cosas en un cuadro de diálogo / panel) y que también se pueden utilizar con EVT_CHAR para restringir la entrada en un campo.
Como otras respuestas en cuenta, es posible hacer esto con un controlador EVT_CHAR
. Usted querrá llamar event.Skip()
de los caracteres que desea para dejar pasar, y no llamarlo para las que desee bloquear. Un matiz es que es probable que también desea llamar event.Skip()
de caracteres de tabulación; pestaña presionando activa el evento EVT_CHAR
, y si usted no llama event.Skip()
, que va a desactivar efectivamente pestaña transversal entre TextCtrl
s.
Esta es una aplicación mínima con dos TextCtrl
s que aceptan números enteros o decimales, con recorrido de trabajo pestaña:
import wx
app = wx.App()
frame = wx.Frame(None, -1, 'simple.py')
panel = wx.Panel(frame)
text_ctrl_1 = wx.TextCtrl(panel, value='123')
text_ctrl_2 = wx.TextCtrl(panel, value='456', pos=(0, 30))
def block_non_numbers(event):
key_code = event.GetKeyCode()
# Allow ASCII numerics
if ord('0') <= key_code <= ord('9'):
event.Skip()
return
# Allow decimal points
if key_code == ord('.'):
event.Skip()
return
# Allow tabs, for tab navigation between TextCtrls
if key_code == ord('\t'):
event.Skip()
return
# Block everything else
return
text_ctrl_1.Bind(wx.EVT_CHAR, block_non_numbers)
text_ctrl_2.Bind(wx.EVT_CHAR, block_non_numbers)
frame.Show()
app.MainLoop()
NumCtrl tiene algunas peculiaridades extraño para mí. Aquí está mi intento de crear un control basado en Número EVT_CHAR y código clave.
Este control permite números, así como todos los códigos de teclas especiales (ctrl combinado, tecla de flecha, tecla de retroceso, etc ...), de modo que copiar y pegar, deshacer-rehacer, seleccione todo etc todavía funciona. Sólo se bloqueará otros caracteres imprimibles (usando string.printable ) y caracteres Unicode (utilizando WXK_NONE )
Otra forma de comprobar y permitir que todos los códigos de teclas especiales se puede encontrar esta respuesta . Este es un enfoque mejor, pero requiere más código.
import string
MyNumCtrl = wx.TextCtrl()
MyNumCtrl.Bind(EVT_CHAR, onChar)
def onChar(self, event):
keycode = event.GetKeyCode()
obj = event.GetEventObject()
val = obj.GetValue()
# filter unicode characters
if keycode == wx.WXK_NONE:
pass
# allow digits
elif chr(keycode) in string.digits:
event.Skip()
# allow special, non-printable keycodes
elif chr(keycode) not in string.printable:
event.Skip() # allow all other special keycode
# allow '-' for negative numbers
elif chr(keycode) == '-':
if val[0] == '-':
obj.SetValue(val[1:])
else:
obj.SetValue('-' + val)
# allow '.' for float numbers
elif chr(keycode) == '.' and '.' not in val:
event.Skip()
return
Consulte el script "Validator.py" en la demostración de wxpython.es exactamente lo que necesitas