Можно ли ограничить TextCtrl для приема чисел только в wxPython?
Вопрос
Я хочу иметь текстовый элемент управления, который принимает только числа.(Только целочисленные значения, такие как 45 или 366)
Каков наилучший способ сделать это?
Решение
IntCtrl
, Masked Edit Control
, и NumCtrl
все они предназначены именно для этого, с разными уровнями контроля.Ознакомьтесь с демонстрацией wx в разделе "Дополнительные окна / элементы управления", чтобы увидеть, как они работают.
(Или, если вы вместо этого действительно хотите сделать это напрямую с помощью необработанного TextCtrl , я думаю, вы хотели бы перехватить события EVT_CHAR, протестировать символы и вызвать evt.Skip(), если это был разрешенный символ.)
Другие советы
Я должен был сделать что-то подобное, проверяя наличие буквенно-цифровых кодов.Подсказка на EVT_CHAR была правильной:
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()
Вы можете попробовать IntCtrl
, EVT_CHAR
, или внедрить новый / существующий валидатор (например ИнтВалидатор).Валидаторы можно использовать для проверки поля (полезно при попытке проверить несколько параметров в диалоговом окне / панели), и они также могут быть использованы с EVT_CHAR для ограничения ввода в поле.
Как отмечают другие ответы, это можно сделать с помощью EVT_CHAR
обработчик.Ты захочешь позвонить event.Skip()
для персонажей, которых вы хотите пропустить, и не вызывайте это для тех, кого вы хотите заблокировать.Один нюанс заключается в том, что вы, вероятно, также хотите позвонить event.Skip()
для символов табуляции;нажатие tab запускает EVT_CHAR
событие, и если вы не позвоните event.Skip()
, вы эффективно отключите обход вкладок между TextCtrl
s.
Вот минимальное приложение, показывающее два TextCtrl
ы, которые принимают целые или десятичные числа, с рабочим обходом табуляции:
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 есть несколько странных для меня причуд.Вот моя попытка создать числовой элемент управления на основе EVT_CHAR и ключевого кода.
Этот элемент управления допускает использование чисел, а также всех специальных кодов клавиш (комбинация ctrl, клавиша со стрелкой, пробел и т.д.), Так что копирование-вставка, отмена-повтор, выделение-все и т.д. По-прежнему работают.Это будет блокировать только другие печатаемые символы (используя строка.для печати) и символы юникода (используя WXK_NONE ( КОД WXK_ONE ))
Другой способ проверить и разрешить все специальные ключевые коды можно найти с помощью этот ответ.Это лучший подход, но требует больше кода.
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
Пожалуйста, проверьте "Validator.py" скрипт в демо-версии wxpython.это именно то, что вам нужно