是否可以将TextCtrl限制为仅在wxPython中接受数字?

是否可以将TextCtrl限制为仅在wxPython中接受数字?,wxpython,textctrl,Wxpython,Textctrl,我想要一个只接受数字的文本控件。(仅为整数值,如45或366) 最好的方法是什么?IntCtrl,屏蔽编辑控件,以及NumCtrl都是为了实现这一点而设计的,具有不同的控制级别。在“更多窗口/控件”下签出wx演示,查看它们是如何工作的 (或者,如果您真的希望直接使用原始文本Ctrl来执行此操作,我认为您应该捕获EVT_CHAR事件,测试字符,并调用EVT.Skip()(如果它是允许的字符)。我必须做类似的事情,检查字母数字代码。关于EVT_CHAR的提示是正确的: class TestPanel

我想要一个只接受数字的文本控件。(仅为整数值,如45或366)


最好的方法是什么?

IntCtrl
屏蔽编辑控件
,以及
NumCtrl
都是为了实现这一点而设计的,具有不同的控制级别。在“更多窗口/控件”下签出wx演示,查看它们是如何工作的


(或者,如果您真的希望直接使用原始文本Ctrl来执行此操作,我认为您应该捕获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()
类测试面板(wx.Panel):
定义初始化(自身,父级):
wx.Panel.\uuuuu init\uuuuuuuuux(自,父,-1)
self.entry=wx.TextCtrl(self,-1)
self.entry.Bind(wx.EVT_CHAR,self.handle_keypress)
def handle_按键(自身,事件):
keycode=event.GetKeyCode()
如果键代码<255:
#有效ASCII码
如果chr(keycode).isalnum():
#有效字母数字字符
event.Skip()

您可以尝试
IntCtrl
EVT\u CHAR
,或者实现新的/现有的验证器(如)。验证器可用于验证字段(在尝试验证对话框/面板上的多个内容时很有用),也可与EVT_CHAR一起用于限制字段中的输入。

请检查wxpython演示中的“Validator.py”脚本。这正是您需要的

正如其他答案所指出的,可以使用
EVT\u CHAR
处理程序来实现这一点。您需要调用
event.Skip()
,用于您想要传递的字符,而不是要阻止的字符。一个细微差别是,您可能还希望为制表符调用
event.Skip()
;按tab键将触发
EVT\u CHAR
事件,如果不调用
event.Skip()
,将有效禁用
TextCtrl
s之间的选项卡遍历

下面是一个最小的应用程序,它显示了两个接受整数或十进制数的
TextCtrl
s,并具有工作选项卡遍历功能:

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()
导入wx
app=wx.app()
frame=wx.frame(无,-1,'simple.py')
面板=宽x.面板(框架)
text\u ctrl\u 1=wx.TextCtrl(面板,值=123')
text\u ctrl\u 2=wx.TextCtrl(面板,值=456',位置=(0,30))
def块_非_编号(事件):
key\u code=event.GetKeyCode()
#允许ASCII数字

如果ord('0')NumCtrl对我来说有一些奇怪的怪癖。下面是我基于EVT_CHAR和keycode创建数字控件的尝试

此控件允许数字以及所有特殊键码(ctrl组合键、箭头键、退格键等),以便复制粘贴、撤消重做、选择全部等仍然有效。它将仅阻止其他可打印字符(使用)和unicode字符(使用)

检查和允许所有特殊钥匙码的另一种方法可以通过找到。这是一种更好的方法,但需要更多的代码

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

我想要相同的方法,但用于浮点数,因此我在类中使用了以下方法:

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

修改上面的答案

您可能还需要启用backspace、del、left-right:
如果在(8127314316)中输入key_code:event.Skip()返回
注意,这些值可能与平台有关。@jake77我相信这些键根本不会触发
EVT_CHAR
(因此在
EVT\u CHAR
处理程序中检查它们是不必要的),不过我稍后会确认。当用户按下del按钮或箭头按钮时,它将如何工作?
    item = wx.TextCtrl(self.panel, -1, str(pose_config['locref_stdev']))
    item.Bind(wx.EVT_CHAR, lambda event: self.force_numeric(event, item))