我有一个列表,
self.list = wx.ListCtrl(panel, -1, style=wx.LC_REPORT | wx.LC_NO_HEADER)
self.list.InsertColumn(col=0, heading='', format=wx.LIST_FORMAT_CENTER, width=150)
self.list.InsertColumn(col=1, heading='', format=wx.LIST_FORMAT_CENTER, width=450)
for person in people:
#this is the issue right here
index = self.list.InsertItem(0, person.age) #one line to insert an item and get the index, and the next line to update the item at that index... two lines to actually put a full entry in.
self.list.SetItem(index=index, column=1, label=person.name)
最初在构造函数中设置listctrl很好,但是如果我想在运行时在listctrl中动态添加/删除项,该怎么办?
我遇到了wx。CallAfter,wx。CallLater、startWorker(来自wx.lib.delayedresult)和wx。计时器
如果你看一下上面的例子,问题是我有一行插入项目,另一行更新项目,使其在刚刚插入的项目上具有正确的名称。因此,如果我有线程轮流删除并向listctrl添加项目,如果我插入一个项目,另一个线程同时插入一个项目,那么我刚刚得到的索引将与更新无关。i、 e.我需要一个原子操作来插入一个项目,包括插入人的年龄和姓名。所以我的第一个问题是,有没有办法将列表项的所有信息插入一行?
如果我不能做到这一点,那么我的下一个问题是,我如何才能完成规定的行为?例如,假设有多个线程随机地为顶行着色、添加和删除:
self.color_timer = wx.Timer(self)
self.Bind(wx.EVT_TIMER, self.item_colorizer, self.color_timer)
self.red_shown = True
self.color_timer.Start(500)
self.delete_timer = wx.Timer(self)
self.Bind(wx.EVT_TIMER, self.item_deleter, self.delete_timer)
self.delete_timer.Start(500)
self.adder_timer = wx.Timer(self)
self.Bind(wx.EVT_TIMER, self.item_queuer, self.adder_timer)
self.adder_timer.Start(400)
下面是我用来添加人、删除人和给顶行上色的方法:
def item_queuer(self, event):
startWorker(consumer=self.item_adder,
workerFn=self.person_generator)
def person_generator(self):
return {'person':random.choice(people)}
def item_adder(self, result):
res = result.get()
person = res['person']
wx.CallAfter(self.list.InsertItem, 0, person.name) # this is the problem right here. If another thread does a color swap in between this line and the next, then this won't work.
wx.CallAfter(self.list.SetItem, index=0, column=1, label=person.name)
def item_deleter(self, event):
wx.CallAfter(self.list.DeleteItem, 0)
def item_colorizer(self, event):
if self.color_timer.IsRunning():
if not self.red_shown:
wx.CallAfter(self.list.SetItemBackgroundColour, 0, wx.RED)
wx.CallAfter(self.list.SetItemTextColour, 0, wx.WHITE)
self.red_shown = True
else:
wx.CallAfter(self.list.SetItemBackgroundColour, 0, wx.BLUE)
wx.CallAfter(self.list.SetItemTextColour, 0, wx.BLACK)
self.red_shown = False
当我运行这个程序时,实际发生的情况是,我的行中有一个人被部分插入(只是年龄),在插入名字之前颜色会发生变化。我注意到listctrl上的InsertItem方法重载,并提供了一个签名,我可以在其中插入ListItem,但我也无法让它工作。
item1 = wx.ListItem()
item1.SetBackgroundColour(wx.GREEN)
item1.SetColumn(0)
item1.SetText(32)
item1.SetColumn(1)
item1.SetText('John')
self.list.InsertItem(item1)
wx_果心WxRealEdStrut: C++断言“RV!= 1”失败了…\src\msw\listctrl。WXLISTCRL::InsertItem()中的cpp(1730):未能在WXLISTCRL中插入项