E 'possibile limitare TextCtrl di accettare solo numeri in wxPython?
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?
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 TextCtrl
s.
Ecco un'applicazione minima che mostra due TextCtrl
s 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