2010-02-04 13 views
5

Potrzebuję zweryfikować pola tekstowe za pomocą wx.Textvalidator. Dowolna proszę mi pomóc to zrobić?wx.TextCtrl i wx.Validator

Jak używać wx.FILTER_ALPHA z walidatorami i jeśli użytkownik podaje błędne dane wejściowe, w jaki sposób mogę im wysłać wiadomość?

Muszę sprawdzić wszystkie wejścia po kliknięciu przycisku zapisu?

Czy ktoś może mi podać przykładowy kod?

Odpowiedz

5

Jest to funkcja wxWidgets i nie jest zaimplementowana w wxPythonie.

http://www.wxpython.org/docs/api/wx.TextValidator-class.html - Nie znaleziono

natomiast:

http://docs.wxwidgets.org/trunk/classwx_text_validator.html http://docs.wxwidgets.org/stable/wx_wxtextvalidator.html

Jest demo Validators w demo wxPython:

import wx 

class TextObjectValidator(wx.PyValidator): 
    """ This validator is used to ensure that the user has entered something 
     into the text object editor dialog's text field. 
    """ 
    def __init__(self): 
     """ Standard constructor. 
     """ 
     wx.PyValidator.__init__(self) 



    def Clone(self): 
     """ Standard cloner. 

      Note that every validator must implement the Clone() method. 
     """ 
     return TextObjectValidator() 


    def Validate(self, win): 
     """ Validate the contents of the given text control. 
     """ 
     textCtrl = self.GetWindow() 
     text = textCtrl.GetValue() 

     if len(text) == 0: 
      wx.MessageBox("A text object must contain some text!", "Error") 
      textCtrl.SetBackgroundColour("pink") 
      textCtrl.SetFocus() 
      textCtrl.Refresh() 
      return False 
     else: 
      textCtrl.SetBackgroundColour(
       wx.SystemSettings_GetColour(wx.SYS_COLOUR_WINDOW)) 
      textCtrl.Refresh() 
      return True 


    def TransferToWindow(self): 
     """ Transfer data from validator to window. 

      The default implementation returns False, indicating that an error 
      occurred. We simply return True, as we don't do any data transfer. 
     """ 
     return True # Prevent wxDialog from complaining. 


    def TransferFromWindow(self): 
     """ Transfer data from window to validator. 

      The default implementation returns False, indicating that an error 
      occurred. We simply return True, as we don't do any data transfer. 
     """ 
     return True # Prevent wxDialog from complaining. 

#---------------------------------------------------------------------- 

class TestValidateDialog(wx.Dialog): 
    def __init__(self, parent): 
     wx.Dialog.__init__(self, parent, -1, "Validated Dialog") 

     self.SetAutoLayout(True) 
     VSPACE = 10 

     fgs = wx.FlexGridSizer(0, 2) 

     fgs.Add((1,1)); 
     fgs.Add(wx.StaticText(self, -1, 
          "These controls must have text entered into them. Each\n" 
          "one has a validator that is checked when the Okay\n" 
          "button is clicked.")) 

     fgs.Add((1,VSPACE)); fgs.Add((1,VSPACE)) 

     label = wx.StaticText(self, -1, "First: ") 
     fgs.Add(label, 0, wx.ALIGN_RIGHT|wx.CENTER) 

     fgs.Add(wx.TextCtrl(self, -1, "", validator = TextObjectValidator())) 

     fgs.Add((1,VSPACE)); fgs.Add((1,VSPACE)) 

     label = wx.StaticText(self, -1, "Second: ") 
     fgs.Add(label, 0, wx.ALIGN_RIGHT|wx.CENTER) 
     fgs.Add(wx.TextCtrl(self, -1, "", validator = TextObjectValidator())) 


     buttons = wx.StdDialogButtonSizer() #wx.BoxSizer(wx.HORIZONTAL) 
     b = wx.Button(self, wx.ID_OK, "OK") 
     b.SetDefault() 
     buttons.AddButton(b) 
     buttons.AddButton(wx.Button(self, wx.ID_CANCEL, "Cancel")) 
     buttons.Realize() 

     border = wx.BoxSizer(wx.VERTICAL) 
     border.Add(fgs, 1, wx.GROW|wx.ALL, 25) 
     border.Add(buttons) 
     self.SetSizer(border) 
     border.Fit(self) 
     self.Layout() 



app = wx.App(redirect=False) 
f = wx.Frame(parent=None) 
f.Show() 
dlg = TestValidateDialog(f) 
dlg.ShowModal() 
dlg.Destroy() 

app.MainLoop() 
+0

Ale jeśli potrzebuję pierwszego pola tekstowego, aby ograniczyć alfabety i drugie pole tekstowe w celu ograniczenia liczb, to co powinienem zrobić? czy muszę napisać dwie oddzielne klasy? – RSK

+0

Tak, najlepiej umieść je w jakiejś wielokrotnie używanej bibliotece narzędzi. –

+0

dziękuję za odpowiedź .... – RSK

1

nie byłem w stanie zrobić przykładowy kod działa poprawnie w moim kodzie (nie używając w ogóle okna dialogowego, ale txtctrl w obrębie panelu), mimo że działa poprawnie w wersji demonstracyjnej (zobacz rysunek).

skończyło się za pomocą fragmentu z innej strony i czują się zobowiązani do udokumentowania go tutaj:

self.tc.GetValidator().Validate(self.tc) 

To był jedyny sposób, że mogę dostać mój niestandardowy kod walidator się nazywać. Wywoływanie self.tc.Validate() nie działało w ogóle ani samo self.Validate(), ani też reprezentacja przekazująca okno jako parametr.

referencyjny: link text

2

Problemem jest prawdopodobnie thast masz ctrl w panelu w oknie dialogowym. Ustaw rekurencyjną flagę w oknie dialogowym, aby umożliwić kod weryfikacyjny szukać kontroli z walidatorami rekurencyjnie:

self.SetExtraStyle(wx.WS_EX_VALIDATE_RECURSIVELY) 
4

Istnieje wiele sposobów, aby to zrobić. Demo wxPython pokazuje, jak zezwalać tylko na cyfry lub tylko alfa. Oto przykład, w oparciu o które:

import wx 
import string 

######################################################################## 
class CharValidator(wx.PyValidator): 
    ''' Validates data as it is entered into the text controls. ''' 

    #---------------------------------------------------------------------- 
    def __init__(self, flag): 
     wx.PyValidator.__init__(self) 
     self.flag = flag 
     self.Bind(wx.EVT_CHAR, self.OnChar) 

    #---------------------------------------------------------------------- 
    def Clone(self): 
     '''Required Validator method''' 
     return CharValidator(self.flag) 

    #---------------------------------------------------------------------- 
    def Validate(self, win): 
     return True 

    #---------------------------------------------------------------------- 
    def TransferToWindow(self): 
     return True 

    #---------------------------------------------------------------------- 
    def TransferFromWindow(self): 
     return True 

    #---------------------------------------------------------------------- 
    def OnChar(self, event): 
     keycode = int(event.GetKeyCode()) 
     if keycode < 256: 
      #print keycode 
      key = chr(keycode) 
      #print key 
      if self.flag == 'no-alpha' and key in string.letters: 
       return 
      if self.flag == 'no-digit' and key in string.digits: 
       return 
     event.Skip() 

######################################################################## 
class ValidationDemo(wx.Frame): 
    """""" 

    #---------------------------------------------------------------------- 
    def __init__(self): 
     """Constructor""" 
     wx.Frame.__init__(self, None, wx.ID_ANY, 
          "Text Validation Tutorial") 

     panel = wx.Panel(self) 
     textOne = wx.TextCtrl(panel, validator=CharValidator('no-alpha')) 
     textTwo = wx.TextCtrl(panel, validator=CharValidator('no-digit')) 

     sizer = wx.BoxSizer(wx.VERTICAL) 
     sizer.Add(textOne, 0, wx.ALL, 5) 
     sizer.Add(textTwo, 0, wx.ALL, 5) 
     panel.SetSizer(sizer) 

# Run the program 
if __name__ == "__main__": 
    app = wx.App(False) 
    frame = ValidationDemo() 
    frame.Show() 
    app.MainLoop() 

Alternatywnym rozwiązaniem byłoby wykorzystanie zamaskowanych kontroli z wykorzystaniem wx.lib.masked. Demo wxPython również ma tego przykłady.