wx.ListCtrl TextEditMixin的数据验证

时间:2018-07-26 16:37:50

标签: wxpython python-3.6 wxpython-phoenix

是否存在一种验证ListCtrl的TextEditMixin中的数据输入的方法或一种优雅的方法 验证中还原数据的操作失败。

问题在于,除非可以验证数据或在验证失败后将其还原为明智的方法,否则任何人都可以在mixin的文本字段中键入任何内容,这可能会在以后造成严重破坏。

如果输入了垃圾,我将无法发现一种内置的方式来还原数据。

我唯一成功的方法是使用wx.CallLater()在编辑之前记录数据,如果编辑的数据未通过验证过程,则将其还原为该数据。

EVT_LIST_END_LABEL_EDIT例程中尝试重新设置数据的尝试失败了,这似乎太早了。

在以下示例中,我希望验证日期和整数(在现实世界中,它可以是任何东西,我正在测试时间格式,日期,整数等)。

该示例有效,但我很难相信,如果输入了垃圾,则既没有验证模式也没有uncommit形式。

我只是找不到它。

import wx
import wx.lib.mixins.listctrl as listmix
import time

class EditableListCtrl(wx.ListCtrl, listmix.TextEditMixin):
    # TextEditMixin allows any column to be edited other than those specifically vetoed
    def __init__(self, parent, ID=wx.ID_ANY, pos=wx.DefaultPosition,
                 size=wx.DefaultSize, style=0):
        """Constructor"""
        wx.ListCtrl.__init__(self, parent, ID, pos, size, style)
        listmix.TextEditMixin.__init__(self)

class Mywin(wx.Frame):
    def __init__(self,parent,title):
        wx.Frame.__init__(self, parent, wx.ID_ANY, title,size= (250,-1))
        self.data = [['A',"20180726","10"],["B","20180725","20"],["C","20180724","30"]]
        self.panel = wx.Panel(self)

        self.listCtrl = EditableListCtrl(self.panel, -1, style = wx.LC_REPORT|wx.LC_HRULES|wx.LC_SINGLE_SEL)
        self.listCtrl.InsertColumn(0, "Name")
        self.listCtrl.InsertColumn(1, "Date", wx.LIST_FORMAT_CENTER)
        self.listCtrl.InsertColumn(2, "Mins", wx.LIST_FORMAT_RIGHT)

        sizer = wx.BoxSizer(wx.HORIZONTAL)
        sizer.Add(self.listCtrl, 0, wx.EXPAND)
        self.panel.SetSizer(sizer)
        mainsizer = wx.BoxSizer(wx.VERTICAL)
        mainsizer.Add(self.panel,1,flag=wx.EXPAND)
        self.SetSizer(mainsizer)

        self.listCtrl.Bind(wx.EVT_LIST_BEGIN_LABEL_EDIT, self.OnVeto)
        self.listCtrl.Bind(wx.EVT_LIST_END_LABEL_EDIT, self.OnMixUpdate)

        for row in self.data:
            self.listCtrl.Append((row))

        self.Show(True)

    def OnMixUpdate(self, event):
        # Validate and Set the changed data
        rowid = event.GetIndex()
        new_data = event.GetLabel()
        colid = event.GetColumn()
        old_data = self.listCtrl.GetItem(rowid,colid)
        old_data = old_data.GetText()

        #Validate Date
        if colid == 1:
            try:
                time.strptime(new_data, '%Y%m%d')
            except ValueError as e: #Issue error and revert to previous data
                wx.MessageBox('Invalid Input - It should be a Date in the format YYYYMMDD !', 'Input Error', wx.OK | wx.ICON_INFORMATION)
                wx.CallLater(10,self.listCtrl.SetItem,rowid,column=colid,label=old_data)
                return

        # Validate Numeric
        if colid == 2:
            try:
                if int(new_data):
                    pass
            except: #Issue error and revert to previous data
                wx.MessageBox('Invalid Entry - Must be an integer', 'Error', wx.OK | wx.ICON_INFORMATION)
                wx.CallLater(10,self.listCtrl.SetItem,rowid,column=colid,label=old_data)
                return

        # Set new data
        self.listCtrl.SetItem(rowid,colid,new_data)

    def OnVeto(self,event):
        if event.Column < 1:
            event.Veto()
            return

ex = wx.App()
Mywin(None,'Text Mixin validation')
ex.MainLoop()

0 个答案:

没有答案