Pergunta

Eu quero ter um controle de texto que aceita apenas números.(Apenas valores inteiros, como 45 ou 366)

Qual é a melhor maneira de fazer isso?

Foi útil?

Solução

IntCtrl, Masked Edit Control, e NumCtrl são todos projetados para fazer exatamente isso, com diferentes níveis de controle. Confira a demonstração do WX em "mais Windows/Controls" para ver como eles funcionam.

(Ou, se você está realmente ansioso para fazer isso diretamente com um texto bruto, acho que você gostaria de pegar eventos EVT_CHAR, testar os personagens e ligar para Evt.skip () se fosse um caractere permitido.)

Outras dicas

Eu tive que fazer algo semelhante, verificando códigos alfanuméricos. A dica em EVT_Char foi a coisa certa:

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()

Você pode tentar IntCtrl, EVT_CHAR, ou a implementação de uma nova ou existente avaliador (como IntValidator).Validadores pode ser usado para validar um campo (útil quando está a tentar validar várias coisas em uma caixa de diálogo do painel/) e eles também podem ser usados com EVT_CHAR para restringir a entrada em um campo.

Como observam outras respostas, é possível fazer isso com um EVT_CHAR manipulador. Você vai querer ligar event.Skip() Para os personagens que você deseja deixar, e não chamá -lo para aqueles que você deseja bloquear. Uma nuance é que você provavelmente também quer ligar event.Skip() para caracteres de guia; Pressionar a guia desencadeia o EVT_CHAR evento, e se você não ligar event.Skip(), você desativará efetivamente a travessia da guia entre TextCtrls.

Aqui está um aplicativo mínimo mostrando dois TextCtrls que aceitam números inteiros ou decimais, com a travessia da guia de trabalho:

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 tem algumas peculiaridades estranhas para mim. Aqui está minha tentativa de criar um controle numérico com base em EVT_Char e KeyCode.

Esse controle permite números, bem como todo o código de chave especial (combo ctrl, chave de seta, backspace etc ...), de modo que a cola de cópia, o desfazer-Redo, a seleção-tudo etc. ainda funcione. Ele apenas bloqueará outros caracteres imprimíveis (usando String.printable) e caracteres unicode (usando Wxk_none)

Outra maneira de verificar e permitir que todo o código de chave especial possa ser encontrado por esta resposta. Esta é uma abordagem melhor, mas requer mais 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

Por favor, verifique o script "validator.py" na demonstração do WXPYTHON. É exatamente o que você precisa

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top