如何获取wx PropertyGrid以允许IntProperty为null / None

时间:2015-04-15 17:11:10

标签: wxpython

PropertyGrid docs提到任何PGProperty您都可以致电SetAutoUnspecified(true)。他们说这应该:

  

通过修改编辑器控件的值(通常通过清除它)将属性的值更改为未指定。目前,这可以使用以下属性:wxIntProperty,wxUIntProperty,wxFloatProperty,wxEditEnumProperty。

但是,为IntProperty设置此功能不起作用;清除它并将鼠标移出单元格会导致它恢复到之前的值或一条迷人的消息:您输入了无效值。按ESC取消编辑

我可以将值初始设为None,但如何让用户清除它?

1 个答案:

答案 0 :(得分:0)

我最终制作了自己的自定义属性和编辑器。这并不完美,但它确实有效。

class NullableIntEditor(propgrid.PyTextCtrlEditor):
    registered = False
    def __init__(self):
        propgrid.PyTextCtrlEditor.__init__(self)

    def CreateControls(self, propGrid, property, pos, sz):
        # Create and populate buttons-subwindow
        wnd = self.CallSuperMethod("CreateControls", propGrid, property, pos, sz)
        wnd.Bind(wx.EVT_CHAR, self.OnChar)
        return wnd

    def OnChar(self, event):
        char_code = event.GetUnicodeKey()
        if not char_code or char_code < ord(' '):
            event.Skip()
        char = chr(char_code)
        if (char in '+-' or char.isdigit()):
            event.Skip()


class NullableIntProperty(propgrid.PyProperty):
    def __init__(self, label, name):
        propgrid.PyProperty.__init__(self, label, name)
        self.SetAutoUnspecified(True)

    def GetEditor(self):
        return "NullableIntEditor"

    def ValueToString(self, value, flags):
        return None if value == '' else str(value)

    def StringToValue(self, s, flags):
        """If failed, return False or (False, None). If success, return tuple (True, newValue)."""
        try:
            if not s:
                v = None
            else:
                v = int(s)
            if self.GetValue() != v:
                return (True, v)
        except (ValueError, TypeError):
            if flags & propgrid.PG_REPORT_ERROR:
                wx.MessageBox("Cannot convert '%s' into a number." % s, "Error")
            else:
                logging.warning("Cannot convert '%s' into a number.", s)
        return False

    def IntToValue(self, v, flags):
        """If failed, return False or (False, None). If success, return tuple (True, newValue)."""
        if (self.GetValue() != v):
            return (True, v)
        return False

    def ValidateValue(self, value, validationInfo):
        if value == '':
            value = None
        if isinstance(value, int) or value is None:
            return (True, value)
        return False