嵌套的wx.PyValidators装饰器模式

2024-09-28 21:32:00 发布

您现在位置:Python中文网/ 问答频道 /正文

我和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)

我遇到了这个问题:当我尝试使用多个decorator(参见下面的代码)时,对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):
        # ...

最后,基本decorator类可能如下所示:

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()

Tags: selfreturncloneinitdefvalidatewinvalidator