wx.ListBox多选中的CTRL-click行为

1 投票
2 回答
1628 浏览
提问于 2025-04-16 21:21

我有一个 wx.ListBox,想让用户像按住 CTRL 键一样进行选择。也就是说,如果你点击一个没有被选中的项目,它会被选中(而不会影响其他已选中的项目);如果你点击一个已经被选中的项目,它会取消选中(同样不会影响其他已选中的项目)。

创建这个列表框的代码是:

    self.myListBox = wx.ListBox(self,
                                    -1,
                                    choices=self.keys,
                                    style =  wx.LB_HSCROLL
                                           | wx.LB_MULTIPLE
                                           | wx.LB_NEEDED_SB
                                           | wx.LB_SORT)
    self.Bind(wx.EVT_LISTBOX, self.OnSelection, self.myListBox)

遇到的问题/疑问:

  • 有没有简单的方法可以做到这一点?wx.LB_MULTIPLEwx.LB_EXTENDED 看起来可能符合我的需求,但我试过这两种方式,似乎没有任何改变。文档中的描述也有点模糊,这两者之间到底有什么区别呢?

  • 我知道可以通过 event.GetSelection() 获取选中项目的 ID,但如果我尝试实现上面的逻辑,也就是:

    if self.myListBox.IsSelected(idx):
        self.myListBox.Deselect(idx)
    else:
        self.myListBox.Select(idx)
    

    事件已经触发,所以它只会取消刚刚选中的项目。我也试过在那之前调用 event.Skip(),但也没有成功。有办法阻止它这样做吗?

  • 我注意到在拖动鼠标进行多选时,event.GetSelection() 会正确返回 ID,像这样 - 3, 2, 1, 0 - 但向下拖动时只会显示第一个 - 0, 0, 0, 0。我猜这只是打印出选中列表中的第一个项目——有没有办法从事件对象中获取这个列表(而不是调用 self.myListBox.GetSelections())?

我在使用 Linux 和 wxPython 版本 2.6.4.0。

2 个回答

0

wxPython 2.6.x 版本非常老旧了。建议你升级到 2.8 或 2.9 系列。我刚刚在 Windows 上运行了 wxPython 2.8.11 的演示,感觉运行得很好。

2

(虽然回答得有点晚,但这可能对记录有帮助。)
我最终为点击事件写了处理程序:

def OnSelection(self, event):
    """Simulate CTRL-click"""
    selection = self.myListBox.GetSelections()

    for i in selection:
        if i not in self.selectedItems:
            # add to list of selected items
            self.selectedItems.append(i)
            self.myListBox.Select(i)
        elif len(selection) == 1:
            # remove from list of selected items
            self.selectedItems.remove(i)
            self.myListBox.Deselect(i)

    for i in self.selectedItems:
        # actually select all the items in the list
        self.myListBox.Select(i)

撰写回答