I have a simple form with a multi line text control and Ok/Cancel buttons on it. I want to check whether the text control has text when Ok button is clicked or not. I’m trying to use the wx.Validator for this purpose, but for some reason it is never get called even the extra style wx.WS_EX_VALIDATE_RECURSIVELY is applied to the parent frame. Here is my code:
import wx
class Validator(wx.PyValidator):
def __init__(self):
wx.PyValidator.__init__(self)
def Clone(self):
return Validator()
def Validate(self, win):
txt_ctrl = self.GetWindow()
if len(txt_ctrl.GetValue()) == 0:
wx.MessageBox('Please, provide a value.', 'Error')
txt_ctrl.SetBackgroundColour('pink')
txt_ctrl.SetFocus()
txt_ctrl.Refresh()
return False
else:
txt_ctrl.SetBackgroundColour(wx.SystemSettings_GetColour(wx.SYS_COLOUR_WINDOW))
txt_ctrl.Refresh()
return True
def TransferToWindow(self):
return True
def TransferFromWindow(self):
return True
class OkCancelPanel(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent, wx.ID_ANY)
self.btn_ok = wx.Button(self, wx.ID_OK)
self.btn_cancel = wx.Button(self, wx.ID_CANCEL)
sizer = wx.BoxSizer(wx.HORIZONTAL)
sizer.Add(self.btn_ok, 0, wx.NORMAL|wx.ALL, 5)
sizer.Add(self.btn_cancel, 0, wx.NORMAL|wx.ALL, 5)
self.SetSizer(sizer)
sizer.Fit(self)
self.Layout()
class Panel(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent, wx.ID_ANY)
self.txt = wx.TextCtrl(self, wx.ID_ANY, style = wx.TE_MULTILINE)
self.okcancel = OkCancelPanel(self)
sizer_txt = wx.StaticBoxSizer(wx.StaticBox(self, wx.ID_ANY, 'Some text here'), wx.HORIZONTAL)
sizer_txt.Add(self.txt, 1, wx.EXPAND, 0)
sizer_txt.Layout()
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(sizer_txt, 1, wx.EXPAND|wx.ALL, 5)
sizer.Add(self.okcancel, 0, wx.NORMAL|wx.ALIGN_RIGHT, 0)
self.SetSizer(sizer)
sizer.Fit(self)
self.Layout()
class Frame(wx.Frame):
def __init__(self, parent):
wx.Frame.__init__(self, parent, wx.ID_ANY, 'Test Frame', size = (400, 300))
self.SetSizeHints(minW = 400, minH = 300)
self.panel = Panel(self)
sizer = wx.BoxSizer(wx.HORIZONTAL)
sizer.Add(self.panel, 1, wx.EXPAND, 0)
self.SetSizer(sizer)
sizer.Fit(self)
self.Layout()
#--Shortcuts--#
self.txt = self.panel.txt
self.btn_ok = self.panel.okcancel.btn_ok
self.btn_cancel = self.panel.okcancel.btn_cancel
class Controller(Frame):
def __init__(self, parent):
Frame.__init__(self, parent)
self.SetExtraStyle(wx.WS_EX_VALIDATE_RECURSIVELY)
self.txt.SetValidator(Validator())
self.Bind(wx.EVT_BUTTON, self.OnButton, self.btn_ok )
def OnButton(self, evt):
self.txt.Validate()
if __name__ == '__main__':
app = wx.App()
frame = Controller(None)
frame.Show()
app.SetTopWindow(frame)
app.MainLoop()
So, what I’m doing wrong?
Sure I can use something like self.txt.GetValidator().Validate(self.txt) in the OnButton method, but I don’t want 🙂
Windows 7 x64, Python 2.7.2, wxPython 2.9.2.4
Instead of:
use: