我想要一个只接受数字的文本控件。 (只需45或366之类的整数值)
这样做的最佳方式是什么?
答案 0 :(得分:5)
我必须做类似的事情,检查字母数字代码。 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()
答案 1 :(得分:4)
IntCtrl
,Masked Edit Control
和NumCtrl
都是为了做到这一点而设计的,具有不同的控制级别。查看“更多Windows /控件”下的wx演示,了解它们的工作原理。
(或者,如果您真的希望直接使用原始TextCtrl执行此操作,我认为您希望捕获EVT_CHAR事件,测试字符,并调用evt.Skip()(如果允许的话)字符。)
答案 2 :(得分:1)
您可以尝试IntCtrl
,EVT_CHAR
或实施新的/现有的验证工具(例如IntValidator)。验证器可用于验证字段(在尝试验证对话框/面板上的多个内容时很有用),它们也可以与EVT_CHAR一起用于限制字段中的输入。
答案 3 :(得分:0)
正如其他答案所述,可以使用EVT_CHAR
处理程序执行此操作。您需要为要通过的字符调用event.Skip()
,而不是为要阻止的字符调用它。一个细微差别是您可能还想要event.Skip()
为标签字符调用;按Tab键会触发EVT_CHAR
事件,如果您不调用event.Skip()
,则会有效禁用TextCtrl
之间的标签遍历。
这是一个最小的应用程序,显示两个接受整数或十进制数的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()
答案 4 :(得分:0)
NumCtrl对我来说有一些奇怪的怪癖。这是我尝试基于EVT_CHAR和键码创建数字控件。
此控件允许数字以及所有特殊键码(ctrl组合键,箭头键,退格键等...),因此复制粘贴,撤消重做,选择全部等仍然有效。它只会阻止其他可打印字符(使用string.printable)和unicode字符(使用WXK_NONE)
this answer可以找到另一种检查和允许所有特殊键码的方法。这是一种更好的方法,但需要更多代码。
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
答案 5 :(得分:0)
除了浮点数外,我也希望这样做,所以我在类中使用了以下方法:
def force_numeric(self, event, edit):
raw_value = edit.GetValue().strip()
keycode = event.GetKeyCode()
if keycode < 255:
print('keycode:', keycode,'chr(keycode) ', chr(keycode))
if chr(keycode).isdigit() or chr(keycode)=='.' and '.' not in raw_value:
print('skip')
event.Skip()
在构造函数中注册事件:
item = wx.TextCtrl(self.panel, -1, str(pose_config['locref_stdev']))
item.Bind(wx.EVT_CHAR, lambda event: self.force_numeric(event, item))
修改上面的答案
答案 6 :(得分:-1)
请在wxpython演示中查看“Validator.py”脚本。这正是你所需要的