2013-10-23 70 views
0

我有一個自定義listctrl在我的應用程序,我想能夠選擇多行(和取消選擇)很像一個ListBox中做。目前我有一個listctrl,我可以抓住單個選擇;然而,一旦我點擊我的listctrl中的另一行,先前的「un-highlights」。我希望它保持突出顯示,除非我再次點擊它 - 所以用戶知道他/她選擇了哪些行(與ListBox工作的方式完全相同)。我嘗試將wx.LC_MULTIPLE_SEL添加到listctrl行,但這不起作用。Python和多個選擇與ListCtrl

幫助?謝謝!

我從以下網站通過Mike Driscoll Python Blog。我適應它來抓取行選擇。本質上,我選擇一行並將索引追加到名爲InfoList的列表中。當我選擇一個新行時,它會正確添加,但我希望該行在實際列表中保持「突出顯示」。然後我可以添加另一行來從列表中刪除一個項目,如果我再次在listctrl中選擇它。

import wx 
import wx.lib.mixins.listctrl as listmix 

InfoList = [] 

musicdata = { 
0 : ("Bad English", "The Price Of Love", "Rock"), 
1 : ("DNA featuring Suzanne Vega", "Tom's Diner", "Rock"), 
2 : ("George Michael", "Praying For Time", "Rock"), 
3 : ("Gloria Estefan", "Here We Are", "Rock"), 
4 : ("Linda Ronstadt", "Don't Know Much", "Rock"), 
5 : ("Michael Bolton", "How Am I Supposed To Live Without You", "Blues"), 
6 : ("Paul Young", "Oh Girl", "Rock"), 
} 

######################################################################## 
class TestListCtrl(wx.ListCtrl): 

    #---------------------------------------------------------------------- 
    def __init__(self, parent, ID=wx.ID_ANY, pos=wx.DefaultPosition, 
       size=wx.DefaultSize, style=0): 
     wx.ListCtrl.__init__(self, parent, ID, pos, size, style) 

######################################################################## 
class TestListCtrlPanel(wx.Panel, listmix.ColumnSorterMixin): 

    #---------------------------------------------------------------------- 
    def __init__(self, parent): 
     wx.Panel.__init__(self, parent, -1, style=wx.WANTS_CHARS) 

     self.list_ctrl = TestListCtrl(self, size=(-1,100), 
         style=wx.LC_REPORT 
         |wx.BORDER_SUNKEN 
         |wx.LC_SORT_ASCENDING 
         ) 
     self.list_ctrl.InsertColumn(0, "Artist") 
     self.list_ctrl.InsertColumn(1, "Title", wx.LIST_FORMAT_RIGHT) 
     self.list_ctrl.InsertColumn(2, "Genre") 

     items = musicdata.items() 
     index = 0 
     for key, data in items: 
      self.list_ctrl.InsertStringItem(index, data[0]) 
      self.list_ctrl.SetStringItem(index, 1, data[1]) 
      self.list_ctrl.SetStringItem(index, 2, data[2]) 
      self.list_ctrl.SetItemData(index, key) 
      index += 1 

     # Now that the list exists we can init the other base class, 
     # see wx/lib/mixins/listctrl.py 
     self.itemDataMap = musicdata 
     listmix.ColumnSorterMixin.__init__(self, 3) 
     self.Bind(wx.EVT_LIST_COL_CLICK, self.OnColClick, self.list_ctrl) 

     ### I ADDED THIS ### 
     self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnSelectMustHave, self.list_ctrl) 

     sizer = wx.BoxSizer(wx.VERTICAL) 
     sizer.Add(self.list_ctrl, 0, wx.ALL|wx.EXPAND, 5) 
     self.SetSizer(sizer) 

    ### I ADDED THIS ### 
    def OnSelectMustHave(self,event):   
     info = event.GetData() 
     InfoList.append(info) 
     print info,InfoList 

    #---------------------------------------------------------------------- 
    # Used by the ColumnSorterMixin, see wx/lib/mixins/listctrl.py 
    def GetListCtrl(self): 
     return self.list_ctrl 

    #---------------------------------------------------------------------- 
    def OnColClick(self, event): 
     print "column clicked" 
     event.Skip() 

######################################################################## 
class MyForm(wx.Frame): 

    #---------------------------------------------------------------------- 
    def __init__(self): 
     wx.Frame.__init__(self, None, wx.ID_ANY, "List Control Tutorial") 

     # Add a panel so it looks the correct on all platforms 
     panel = TestListCtrlPanel(self) 

#---------------------------------------------------------------------- 
# Run the program 
if __name__ == "__main__": 
    app = wx.App(False) 
    frame = MyForm() 
    frame.Show() 
    app.MainLoop() 
+0

我添加工作代碼(我的方式太長了,只是簡單地加入)。 – mcfly

+0

如果我直接複製/粘貼你的代碼(上圖),它可以很好地在windows7上選擇倍數...你在什麼操作系統上? –

+0

Windows 8 ...請不要告訴我這是我必須對Windows 8不喜歡的另一件事! – mcfly

回答

1

其毛但這會做你想要什麼

def OnSelectMustHave(self,event):   
    info = event.GetData() 
    InfoList.append(info) 
    def do_select(): 
      map(lambda x:self.list_ctrl.Select(x,1) ,set(InfoList)) 

    wx.CallLater(100,do_select) 
    print info,InfoList 
    return 

但是因爲你有InfoList類似下面的解決方案選擇的元素列表可能工作上面

def OnSelectMustHave(self,event):   
    info = event.GetData() 
    InfoList.append(info) 
    map(lambda x:self.list_ctrl.SetItemBackgroundColour(x,wx.LIGHT_GREY) ,set(InfoList)) 
    print info,InfoList 
    return 
1

有規律的ListCtrl工作:

import wx 

######################################################################## 
class MyForm(wx.Frame): 

    #---------------------------------------------------------------------- 
    def __init__(self): 
     wx.Frame.__init__(self, None, wx.ID_ANY, "List Control Tutorial") 

     # Add a panel so it looks the correct on all platforms 
     panel = wx.Panel(self, wx.ID_ANY) 
     self.index = 0 

     self.list_ctrl = wx.ListCtrl(panel, size=(-1,100), 
         style=wx.LC_REPORT 
         |wx.BORDER_SUNKEN 
         ) 
     self.list_ctrl.InsertColumn(0, 'Subject') 
     self.list_ctrl.InsertColumn(1, 'Due') 
     self.list_ctrl.InsertColumn(2, 'Location', width=125) 

     btn = wx.Button(panel, label="Add Line") 
     btn.Bind(wx.EVT_BUTTON, self.add_line) 

     sizer = wx.BoxSizer(wx.VERTICAL) 
     sizer.Add(self.list_ctrl, 1, wx.ALL|wx.EXPAND, 5) 
     sizer.Add(btn, 0, wx.ALL|wx.CENTER, 5) 
     panel.SetSizer(sizer) 

    #---------------------------------------------------------------------- 
    def add_line(self, event): 
     line = "Line %s" % self.index 
     self.list_ctrl.InsertStringItem(self.index, line) 
     self.list_ctrl.SetStringItem(self.index, 1, "01/19/2010") 
     self.list_ctrl.SetStringItem(self.index, 2, "USA") 
     self.index += 1 

#---------------------------------------------------------------------- 
# Run the program 
if __name__ == "__main__": 
    app = wx.App(False) 
    frame = MyForm() 
    frame.Show() 
    app.MainLoop() 

如果我修改此使用你提到的兩個混入,它也可以工作:

import wx 
import wx.lib.mixins.listctrl as listmix 

######################################################################## 
class MyListCtrl(wx.ListCtrl, listmix.TextEditMixin, listmix.ColumnSorterMixin): 
    """""" 

    #---------------------------------------------------------------------- 
    def __init__(self, parent): 
     """Constructor""" 
     wx.ListCtrl.__init__(self, parent, style=wx.LC_REPORT|wx.BORDER_SUNKEN) 
     listmix.ColumnSorterMixin.__init__(self, 3) 
     listmix.TextEditMixin.__init__(self) 

    #---------------------------------------------------------------------- 
    def GetListCtrl(self): 
     return self 

######################################################################## 
class MyForm(wx.Frame): 

    #---------------------------------------------------------------------- 
    def __init__(self): 
     wx.Frame.__init__(self, None, wx.ID_ANY, "List Control Tutorial") 

     # Add a panel so it looks the correct on all platforms 
     panel = wx.Panel(self, wx.ID_ANY) 
     self.index = 0 

     self.list_ctrl = MyListCtrl(panel) 
     self.list_ctrl.InsertColumn(0, 'Subject') 
     self.list_ctrl.InsertColumn(1, 'Due') 
     self.list_ctrl.InsertColumn(2, 'Location', width=125) 

     btn = wx.Button(panel, label="Add Line") 
     btn.Bind(wx.EVT_BUTTON, self.add_line) 

     sizer = wx.BoxSizer(wx.VERTICAL) 
     sizer.Add(self.list_ctrl, 1, wx.ALL|wx.EXPAND, 5) 
     sizer.Add(btn, 0, wx.ALL|wx.CENTER, 5) 
     panel.SetSizer(sizer) 

    #---------------------------------------------------------------------- 
    def add_line(self, event): 
     line = "Line %s" % self.index 
     self.list_ctrl.InsertStringItem(self.index, line) 
     self.list_ctrl.SetStringItem(self.index, 1, "01/19/2010") 
     self.list_ctrl.SetStringItem(self.index, 2, "USA") 
     self.index += 1 

#---------------------------------------------------------------------- 
# Run the program 
if __name__ == "__main__": 
    app = wx.App(False) 
    frame = MyForm() 
    frame.Show() 
    app.MainLoop() 

我使用wxPython的2.6和wxPython的2.8.12在Windows 7上。我可以一次選擇多個項目並取消選擇它們。

+0

我應該更詳細。我不知道你如何選擇多行。他們的方式我看到它是按住「Ctrl」並選擇。我希望有一種不同的方式,我可以單獨左鍵單擊每一個,並且它們都保持突出顯示。 – mcfly