Domanda

Voglio avere un controllo di testo che accetta solo numeri. (A soli valori interi come 45 o 366)

Qual è il modo migliore per fare questo?

È stato utile?

Soluzione

IntCtrl, Masked Edit Control e NumCtrl sono tutti progettati per fare proprio questo, con diversi livelli di controllo. Checkout la WX demo sotto "Altre Finestre / Controlli" per vedere come funzionano.

(o, se si sta invece davvero impaziente di farlo direttamente con un TextCtrl cruda, credo che ci si vuole catturare eventi EVT_CHAR, testare i personaggi, e chiamare evt.Skip () se si trattava di un permesso personaggio.)

Altri suggerimenti

che dovevo fare qualcosa di simile, controllando per i codici alfanumerici. La punta sulla EVT_CHAR era la cosa giusta:

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

Si può provare IntCtrl, EVT_CHAR, o implementare un nuovo / validatore esistente (come IntValidator ). I validatori possono essere utilizzati per convalidare un campo (utile quando si cerca di convalidare più cose in una finestra / pannello) e possono essere utilizzati anche con EVT_CHAR per limitare l'ingresso in un campo.

Come altre risposte di notare, è possibile farlo con un gestore EVT_CHAR. Ti consigliamo di chiamare event.Skip() per i caratteri che si desidera lasciar passare, e non lo chiamano per quelli che si desidera bloccare. Una sfumatura è che probabilmente anche desidera chiamare event.Skip() per i caratteri di tabulazione; scheda premendo attiva l'evento EVT_CHAR, e se non si chiama event.Skip(), ti disattivare efficacemente scheda attraversamento tra TextCtrls.

Ecco un'applicazione minima che mostra due TextCtrls che accettano numeri interi o decimali, con scheda di lavoro trasversale:

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 ha alcune stranezze strano per me. Qui è il mio tentativo di creare un controllo in base a numero EVT_CHAR e codice.

Questo controllo permette numeri così come tutte codice chiave speciale (ctrl combinata, sulla tastiera, backspace, ecc ...), in modo che copia-incolla, scuci-cuci, selezionare, tutto funziona ancora, ecc. Si bloccherà solo altri caratteri stampabili (utilizzando string.printable ) e caratteri unicode (utilizzando WXK_NONE )

Un altro modo per controllare e consentire a tutti keycode speciale può essere trovato da questa risposta . Questo è un approccio migliore, ma richiede più codice.

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

Si prega di verificare script "Validator.py" in wxPython demo. è esattamente quello che ti serve

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top