代码之家  ›  专栏  ›  技术社区  ›  Kevin S

wxPython listctrl insertitem和SetItem同时出现

  •  0
  • Kevin S  · 技术社区  · 7 年前

    我有一个列表,

        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中插入项

    0 回复  |  直到 7 年前
    推荐文章