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

5voto

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

0voto

auzn Punkte 193

NumCtrl hat für mich einige seltsame Eigenheiten. Hier ist mein Versuch, eine Zahl Steuerung basierend auf EVT_CHAR und Keycode zu erstellen.

Dieses Steuerelement erlaubt sowohl Zahlen als auch alle Sondertasten (Strg-Kombination, Pfeiltaste, Rücktaste usw.), so dass Kopieren/Einfügen, Rückgängig machen, Alles auswählen usw. weiterhin funktionieren. Es wird nur andere druckbare Zeichen blockieren (mit string.printable ) und Unicode-Zeichen (mit WXK_NONE )

Eine andere Möglichkeit, alle speziellen Schlüsselcodes zu prüfen und zuzulassen, finden Sie unter diese Antwort . Dies ist ein besserer Ansatz, erfordert aber mehr 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

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