11 Stimmen

Ist es möglich, TextCtrl zu beschränken, nur Zahlen in wxPython zu akzeptieren?

Ich möchte ein Textsteuerelement haben, das nur Zahlen akzeptiert. (Nur ganzzahlige Werte wie 45 oder 366)

Wie lässt sich dies am besten bewerkstelligen?

10voto

Jay P. Punkte 641

Ich musste etwas Ähnliches tun und nach alphanumerischen Codes suchen. Der Tipp zu EVT_CHAR war genau richtig:

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

8voto

tom10 Punkte 63374

IntCtrl , Masked Edit Control y NumCtrl sind alle für genau diesen Zweck konzipiert, mit unterschiedlichen Kontrollstufen. Schauen Sie sich die wx-Demo unter "More Windows/Controls" an, um zu sehen, wie sie funktionieren.

(Oder, wenn Sie stattdessen wirklich freuen sich darauf, dies direkt mit einem rohen TextCtrl zu tun, ich denke, Sie möchten EVT_CHAR Ereignisse zu fangen, testen Sie die Zeichen, und rufen Sie evt.Skip(), wenn es ein erlaubtes Zeichen war).

1voto

MarsianMan Punkte 11

Sie können versuchen IntCtrl , EVT_CHAR , oder implementieren Sie einen neuen/vorhandenen Validator (wie IntValidator ). Validatoren können verwendet werden, um ein Feld zu validieren (nützlich, wenn man versucht, mehrere Dinge in einem Dialog/Panel zu validieren) und sie können auch mit EVT_CHAR verwendet werden, um die Eingabe in ein Feld zu beschränken.

1voto

Mark Amery Punkte 124946

Wie andere Antworten zeigen, ist es möglich, dies mit einer EVT_CHAR Bearbeiter. Sie sollten Folgendes aufrufen event.Skip() für die Zeichen, die Sie durchlassen wollen, und nicht für die, die Sie blockieren wollen. Eine Nuance ist, dass Sie wahrscheinlich auch die Funktion event.Skip() für Tabulatorzeichen; das Drücken von Tabulator löst die EVT_CHAR Ereignis, und wenn Sie nicht event.Skip() deaktivieren Sie effektiv den Tab-Traversal zwischen TextCtrl s.

Hier ist eine Minimalanwendung mit zwei TextCtrl s, die Integer- oder Dezimalzahlen akzeptieren, mit funktionierendem Tabulator-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()

1voto

Ich wollte das Gleiche, aber für Floats, also habe ich die folgende Methode in der Klasse verwendet:

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

um das Ereignis im Konstruktor zu registrieren:

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

Abänderung der obigen Antwort

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X