Est-il possible de limiter TextCtrl d'accepter que des chiffres dans wxPython?

StackOverflow https://stackoverflow.com/questions/1369086

  •  21-09-2019
  •  | 
  •  

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?

Était-ce utile?

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 TextCtrls.

Voici une application minimale montrant deux TextCtrls 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

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top