Is it possible to limit TextCtrl to accept numbers only in wxPython?
Masked Edit Control, and
NumCtrl are all designed to do just this, with different levels of control. Checkout the wx demo under "More Windows/Controls" to see how they work.
(Or, if you're instead really looking forward to doing this directly with a raw TextCtrl, I think you'd want to catch EVT_CHAR events, test the characters, and call evt.Skip() if it was an allowed character.)
I had to do something similar, checking for alphanumeric codes. The tip on EVT_CHAR was the right thing:
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()
You can try
EVT_CHAR, or implement a new/existing validator (like IntValidator). Validators can be used to validate a field (useful when trying to validate multiple things on a dialog/panel) and they can also be used with EVT_CHAR to restrict input in a field.
As other answers note, it's possible to do this with an
EVT_CHAR handler. You'll want to call
event.Skip() for the characters you want to let through, and not call it for the ones you want to block. One nuance is that you probably also want to call
event.Skip() for tab characters; pressing tab triggers the
EVT_CHAR event, and if you don't call
event.Skip(), you'll effectively disable tab traversal between
Here's a minimal application showing two
TextCtrls that accept integer or decimal numbers, with working tab 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()