嵌套的wx.PyValidators装饰模式

时间:2015-10-20 20:15:06

标签: python oop wxpython wxwidgets

我正在与wxPython's validators合作。我有一个文本字段,我只想接受数字,并且是必需的(不是留空。)一个快速的方法是简单地创建一个验证器类来完成这两件事,但是,我想做使用decorator pattern,并使用两个独立的,有凝聚力的验证器。这样我可以拥有可重用的验证器类,我可以在整个应用程序中混合和匹配。

例如,我希望能够分配这样的验证器:

requiredAndDigitsOnly = DigitValidator(RequiredValidator(CustomValidator()))
textField = wx.TextCtrl(sbSizer.GetStaticBox(), wx.ID_ANY,\
    wx.EmptyString, wx.DefaultPosition, wx.DefaultSize,\
    validator=requiredAndDigitsOnly)

我遇到了这个问题:当我尝试使用多个装饰器时(请参阅下面的代码),对self.GetWindow()的调用会返回None,所以验证停止,因为它无法获取正在验证的窗口的句柄。必须是因为toBeValidated没有指向正确的窗口。 如何在wx.PyValidator中使用嵌套验证器?

这有效:RequiredValidator(CustomValidator())但不是:DigitValidator(RequiredValidator(CustomValidator()))

Custom Validatorwx.PyValidator的子类:

import wx

class CustomValidator(wx.PyValidator):
    ''' 
    This is a basic validator that inherits from
    PyValidator.
    '''
    def __init__(self):
        super(CustomValidator, self).__init__()

    def Clone(self):
        # Every validator must implement a Clone method.
        return CustomValidator()

    def Validate(self, win):
        return True

    def TransferToWindow(self):
        return True
    def TransferFromWindow(self):
        return True

RequiredValidatorDigitValidator是基础装饰器类的子类。以下是RequiredValidator的外观(DigitValidator几乎相同,除了处理验证方式不同):

class RequiredValidator(ValidatorDecorator):

    def __init__(self, toBeDecorated):
        super(RequiredValidator, self).__init__(toBeDecorated)
        # Now add customization to the validator.
        self.Bind(wx.EVT_SET_FOCUS, self.onClick)

    def Clone(self):
        # Every validator must implement a Clone method.
        return self.__class__(self.toBeDecorated)

    def Validate(self, win):
        textControl = self.GetWindow()
        value = textControl.GetValue()

        if not len(value):
            textControl.SetBackgroundColour('#FFFAC5')
            return False
        return super(RequiredValidator, self).Validate(win)

    def onClick(self, event):
        # ...

最后,基础装饰器类可能如下所示:

class ValidatorDecorator(wx.PyValidator):
    '''
        Abstract decorator class
    '''
    def __init__(self, toBeDecorated):
        self.toBeDecorated = toBeDecorated
        super(ValidatorDecorator, self).__init__()

    def Clone(self):
        # Every validator must implement a Clone method.
        return self.toBeDecorated.Clone()

    def Validate(self, win):
        # Delegate this.
        return self.toBeDecorated.Validate(win)

    def GetWindow(self):
        return super(self.__class__, self).GetWindow()

    def TransferToWindow(self):
        # Delegate this.
        return self.toBeDecorated.TransferToWindow()

    def TransferFromWindow(self):
        # Delegate this.
        return self.toBeDecorated.TransferFromWindow()

0 个答案:

没有答案