Kev*_*n S 5 wxpython python-3.x
我有一个列表控件,
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)
Run Code Online (Sandbox Code Playgroud)
最初在构造函数中设置 listctrl 效果很好,但是如果我想在运行时动态添加/删除 listctrl 中的项目怎么办?
我遇到过 wx.CallAfter、wx.CallLater、startWorker (来自 wx.lib.delayedresult)和 wx.Timer
如果您查看上面的示例,问题是我有一行插入该项目,另一行更新该项目以在刚刚插入的项目上具有正确的名称。因此,如果我有线程轮流删除和添加项目到 listctrl,如果我插入一个项目,而另一个线程同时插入一个项目,那么我刚刚获得的索引将与更新无关。即我需要一个原子操作来插入一个项目,其中包括插入人的年龄和人的名字。所以我的第一个问题是,有没有办法将列表项的所有信息插入一行?
如果我不能做到这一点,那么我的下一个问题是我怎样才能完成规定的行为?例如,假设有线程随机对顶行进行着色、添加和删除:
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)
Run Code Online (Sandbox Code Playgroud)
下面是我用来添加人员、删除人员以及为顶行着色的方法:
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
Run Code Online (Sandbox Code Playgroud)
当我运行这个程序时,实际发生的情况是,我最终得到了部分插入人员的行(只是年龄),并且在插入姓名之前颜色发生了变化。我注意到 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)
Run Code Online (Sandbox Code Playgroud)
wx._core.wxAssertionError:C++ 断言“rv!= -1”在 wxListCtrl::InsertItem() 中的 ....\src\msw\listctrl.cpp(1730) 处失败:无法在 wxListCtrl 中插入项目