wxPython 验证器无法按预期工作
我在wxPython中写了一个对话框,里面有两个下拉框,并且我给它们加了一个自定义的验证器,目的是确保如果输入了值,那这个值必须是数字字符串。问题是,这些验证器没有被调用。我哪里做错了呢?
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
- 用
PyValidator
代替Validator
- 你的
ComboBox
和Button
的父级应该是Dialog
,而不是Panel
下面这个版本的代码应该能正常工作:
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()
0
我也不知道为什么,但是复制这个 wxPython示例 是没问题的。
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
这是wxWidgets中的一个小问题。如果父窗口不是wx.Dialog的子类,你就需要手动调用“TransferDataToWindow”和“TransferDataFromWindow”这两个方法来进行数据传输。在这里,你使用wx.Panel作为下拉框的父窗口,所以数据传输不会自动进行。