wxPython验证器未按预期工作

时间:2010-09-29 21:30:46

标签: python wxpython

我在wxPtyhon中编写了一个带有两个组合框的对话框,我附加了一个自定义验证器,目的是确保在键入值时,它是一个数字字符串。问题是,没有调用验证器。我做错了什么?

    import wx

    # my custom validator class

    class NumericObjectValidator(wx.Validator):
       def __init__(self):
          wx.Validator.__init__(self)

       def Clone(self):
          return NumericObjectValidator()

       # Why isn't this method being called when the user types in the CB field?
       def Validate(self, win):
          cbCtrl = self.GetWindow()
          text = cbCtrl.GetValue()
          print 'control value=',text
          return True

    class SizeDialog(wx.Dialog):
       def __init__(self, parent):
          wx.Dialog.__init__(self, parent, -1, 'Select Size', size=(200,135))

          panel = wx.Panel(self, -1, size=self.GetClientSize())

          sizes = map(str, range(3,21))
          wx.StaticText(panel, -1, 'Rows:', pos=(10, 15))
          self.rows = wx.ComboBox(panel, -1, value='8', choices=sizes,
             style=wx.CB_DROPDOWN, pos=(80,15), validator=NumericObjectValidator())

          wx.StaticText(panel, -1, 'Columns:', pos=(10,40))
          self.cols = wx.ComboBox(panel, -1, choices=sizes, style=wx.CB_DROPDOWN,
             pos=(80,40), value='8', validator=NumericObjectValidator())

          cancel = wx.Button(panel,wx.ID_CANCEL,'Cancel', pos=(20,75))
          wx.Button(panel,wx.ID_OK,'OK', pos=(100,75)).SetDefault()

       def TransferToWindow(self):
          return True

       def TransferFromWindow(self):
          return True

       def get_size(self):
          r = int(self.rows.GetValue())
          c = int(self.cols.GetValue())
          return (c,r)

    if __name__ == "__main__":
       app = wx.App(0)
       dlg = SizeDialog(None)
       dlg.ShowModal()
       dlg.Destroy()

3 个答案:

答案 0 :(得分:2)

这是wxWidgets中的一个怪癖。如果父级不是wx.Dialog的(子类),则必须手动调用wx.Window上的方法“TransferDataToWindow”和“TransferDataFromWindow”。在这里,您使用wx.Panel作为组合框的父级,因此不会自动调用数据传输。

答案 1 :(得分:0)

我不知道为什么,但复制wxPython demo可以正常工作。

import wx
import string

# my custom validator class

class NumericObjectValidator(wx.PyValidator):
    def __init__(self):
        wx.PyValidator.__init__(self)
        self.Bind(wx.EVT_CHAR, self.OnChar)

    def Clone(self):
        return NumericObjectValidator()

    def Validate(self, win):
        tc = self.GetWindow()
        val = tc.GetValue()

        for x in val:
            if x not in string.digits:
                return False

        return True


    def OnChar(self, event):
        key = event.GetKeyCode()

        if key < wx.WXK_SPACE or key == wx.WXK_DELETE or key > 255:
            event.Skip()
            return

        if chr(key) in string.digits:
            event.Skip()

        return


class SizeDialog(wx.Dialog):
   def __init__(self, parent):
      wx.Dialog.__init__(self, parent, -1, 'Select Size', size=(200,135))

      panel = wx.Panel(self, -1, size=self.GetClientSize())

      sizes = map(str, range(3,21))
      wx.StaticText(panel, -1, 'Rows:', pos=(10, 15))
      self.rows = wx.ComboBox(panel, -1, value='8', choices=sizes,
         style=wx.CB_DROPDOWN, pos=(80,15), validator=NumericObjectValidator())

      wx.StaticText(panel, -1, 'Columns:', pos=(10,40))
      self.cols = wx.ComboBox(panel, -1, style=wx.CB_DROPDOWN, validator=NumericObjectValidator())

      cancel = wx.Button(panel,wx.ID_CANCEL,'Cancel', pos=(20,75))
      wx.Button(panel,wx.ID_OK,'OK', pos=(100,75)).SetDefault()

   def TransferToWindow(self):
      return True

   def TransferFromWindow(self):
      return True

   def get_size(self):
      r = int(self.rows.GetValue())
      c = int(self.cols.GetValue())
      return (c,r)

if __name__ == "__main__":
   app = wx.App(0)
   dlg = SizeDialog(None)
   dlg.ShowModal()
   dlg.Destroy()

答案 2 :(得分:0)

  1. 使用PyValidator代替Validator
  2. 您的ComboBoxButton的父级应该是Dialog而不是Panel
  3. 以下版本的代码可以正常工作:

        import wx
    
        # my custom validator class
    
        class NumericObjectValidator(wx.PyValidator):
    
            def __init__(self):
                wx.PyValidator.__init__(self)
    
            def Clone(self):
                return NumericObjectValidator()
    
            # Why isn't this method being called when the user types in the CB
            # field?
            def Validate(self, win):
                cbCtrl = self.GetWindow()
                text = cbCtrl.GetValue()
                print 'control value=', text
                return True
    
            def TransferToWindow(self):
                return True
    
            def TransferFromWindow(self):
                return True
    
        class SizeDialog(wx.Dialog):
    
            def __init__(self, parent):
                wx.Dialog.__init__(
                    self, parent, -1, 'Select Size', size=(200, 135))
    
                sizes = map(str, range(3, 21))
                wx.StaticText(self, -1, 'Rows:', pos=(10, 15))
                self.rows = wx.ComboBox(self, -1, value='8', choices=sizes,
                                        style=wx.CB_DROPDOWN, pos=(80, 15), validator=NumericObjectValidator())
    
                wx.StaticText(self, -1, 'Columns:', pos=(10, 40))
                self.cols = wx.ComboBox(
                    self, -1, choices=sizes, style=wx.CB_DROPDOWN,
                    pos=(80, 40), value='8', validator=NumericObjectValidator())
    
                cancel = wx.Button(self, wx.ID_CANCEL, 'Cancel', pos=(20, 75))
                wx.Button(self, wx.ID_OK, 'OK', pos=(100, 75)).SetDefault()
    
            def get_size(self):
                r = int(self.rows.GetValue())
                c = int(self.cols.GetValue())
                return (c, r)
    
        if __name__ == "__main__":
            app = wx.App(0)
            dlg = SizeDialog(None)
            dlg.ShowModal()
            dlg.Destroy()
    
相关问题