是否存在一种验证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()