Est-il possible de limiter TextCtrl d'accepter que des chiffres dans wxPython?
Question
Je veux avoir un contrôle de texte qui accepte uniquement les numéros. (Seulement des nombres entiers tels que 45 ou 366)
Quelle est la meilleure façon de le faire?
La solution
IntCtrl
, Masked Edit Control
et NumCtrl
sont tous conçus pour tout cela, avec différents niveaux de contrôle. Checkout la démo WX sous la rubrique « Plus Windows / contrôles » pour voir comment ils fonctionnent.
(Ou, si vous plutôt vraiment hâte de le faire directement avec un TextCtrl cru, je pense que vous voulez capturer des événements EVT_CHAR, tester les personnages, et appeler evt.Skip () si elle était un permis caractère.)
Autres conseils
Je devais faire quelque chose de similaire, la vérification des codes alphanumériques. La pointe sur EVT_CHAR était la bonne chose:
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()
Vous pouvez IntCtrl
, EVT_CHAR
, ou mettre en œuvre un nouveau / validateur existant (comme IntValidator ). Validateurs peuvent être utilisées pour valider un champ (utile lorsque vous essayez de valider plusieurs choses sur un dialogue / panneau) et ils peuvent également être utilisés avec EVT_CHAR pour restreindre l'entrée dans un champ.
Comme d'autres réponses noter, il est possible de le faire avec un gestionnaire d'EVT_CHAR
. Vous voulez appeler event.Skip()
pour les personnages que vous voulez laisser passer, et ne pas l'appeler pour ceux que vous voulez bloquer. Une nuance est que vous voulez sans doute aussi appeler event.Skip()
pour les caractères de tabulation; presser la touche tab déclenche l'événement EVT_CHAR
, et si vous ne l'appelez pas event.Skip()
, vous désactiver efficacement onglet traversal entre TextCtrl
s.
Voici une application minimale montrant deux TextCtrl
s qui acceptent des nombres entiers ou décimaux, avec le travail onglet traversal:
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 a quelques bizarreries étranges pour moi. Voici ma tentative de créer un contrôle basé sur EVT_CHAR Nombre et keycode.
Ce contrôle permet nombres ainsi que tous keycode spécial (combo ctrl, du clavier, backspace etc ...), de sorte que copier-coller, Redo, tout sélectionner etc fonctionne toujours. Il bloque uniquement les autres caractères imprimables (en utilisant string.printable ) et les caractères unicode (en utilisant WXK_NONE )
Une autre façon de vérifier et de permettre à tous keycode spéciale se trouve par cette réponse . Ceci est une meilleure approche mais nécessite plus de code.
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
S'il vous plaît vérifier script "Validator.py" dans wxpython démo. il est exactement ce dont vous avez besoin