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

发布于 2024-08-04 03:08:42 字数 65 浏览 4 评论 0原文

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

执行此操作的最佳方法是什么?

I want to have a text control that only accepts numbers. (Just integer values like 45 or 366)

What is the best way to do this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

面犯桃花 2024-08-11 03:08:42

我必须做类似的事情,检查字母数字代码。 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()

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()
剪不断理还乱 2024-08-11 03:08:42

IntCtrlMasked Edit ControlNumCtrl 都旨在实现此目的,并具有不同级别的控制。查看“更多 Windows/控件”下的 wx 演示,了解它们是如何工作的。

(或者,如果您确实希望直接使用原始 TextCtrl 执行此操作,我认为您需要捕获 EVT_CHAR 事件,测试字符,并调用 evt.Skip() (如果它是允许的字符)。)

IntCtrl, 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.)

浅笑依然 2024-08-11 03:08:42

您可以尝试 IntCtrlEVT_CHAR 或实现新的/现有的验证器(例如 IntValidator)。验证器可用于验证字段(在尝试验证对话框/面板上的多个内容时很有用),它们还可以与 EVT_CHAR 一起使用来限制字段中的输入。

You can try IntCtrl, 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.

铜锣湾横着走 2024-08-11 03:08:42

正如其他答案所指出的,可以使用 EVT_CHAR 处理程序来完成此操作。您需要为要允许通过的字符调用 event.Skip(),而不是为要阻止的字符调用它。一个细微差别是您可能还想为制表符调用 event.Skip() ;按 T​​ab 键会触发 EVT_CHAR 事件,如果您不调用 event.Skip(),您将有效禁用 TextCtrl 之间的 Tab 键遍历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()

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 TextCtrls.

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()
-黛色若梦 2024-08-11 03:08:42

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

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

修改上面的答案

I wanted the same but for floats, so I used the following method in the class:

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

to register the event in the constructor:

    item = wx.TextCtrl(self.panel, -1, str(pose_config['locref_stdev']))
    item.Bind(wx.EVT_CHAR, lambda event: self.force_numeric(event, item))

Modifying the answer above

亽野灬性zι浪 2024-08-11 03:08:42

NumCtrl 对我来说有一些奇怪的怪癖。这是我尝试创建基于 EVT_CHAR 和键码的数字控件。

该控件允许数字以及所有特殊键码(ctrl组合、箭头键、退格键等...),因此复制粘贴、撤消重做、全选等仍然有效。它只会阻止其他可打印字符(使用 string.printable )和 unicode 字符(使用 WXK_NONE< /a>)

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

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

NumCtrl has some weird quirks to me. Here is my attempt to create a Number control based on EVT_CHAR and keycode.

This control allow numbers as well as all special keycode (ctrl combo, arrow key, backspace etc...), so that copy-paste, undo-redo, select-all etc still works. It will only block other printable characters (using string.printable) and unicode characters (using WXK_NONE)

Another way to check and allow all special keycode can be found by this answer. This is a better approach but requires more code.

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
无人接听 2024-08-11 03:08:42

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

Please check "Validator.py" script in wxpython demo. it is exactly what you need

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文