Search code examples
pythonwxpython

wxPython List Ctrl: Add Column and Images


I am getting an error trying to make a column and add images to "browserlist". The error from the command line says "can't add column in non report mode".

How can I simply add this icons and their corresponding names, i.e. "Google chrome" to the list ctrl?

images=['/Desktop/chromelogo.png', 'Desktop/firefoxlogo.png']
browserlist=wx.ListCtrl(panel, pos=(255, 100), size=(220, 100))
browserlist.InsertColumn(0, '')

self.il = wx.ImageList(40,40,True)
for i in images:
    self.il.Add(wx.Bitmap(i))

I want it to look kind of like the leftside of the window below: enter image description here


Solution

  • Look for the ListCtrl example in the wxPython demo (install it now if you do not have it). It has icons prepended to the row text. To be able to add columns you have to set the style to wx.LC_REPORT (EDIT) (you will be limited to 16x16 icons in that mode) (EDIT3, not true).

    EDIT2: Full example added (modified wxPython demo ListCtrl example)

    EDIT4: Example modification, remove list unpacking.

    with screenshot

    import  wx
    
    test_list_data = {
    1 : ("New", "Explanation text new"),
    2 : ("Open", "Explanation text open"),
    3 : ("Copy", "Explanation text copy"),
    4 : ("Paste", "Explanation text paste")}
    
    class TestListCtrlPanel(wx.Panel):
        def __init__(self, *args, **kwds):
            wx.Panel.__init__(self, *args, **kwds)
    
            sizer = wx.BoxSizer(wx.VERTICAL)
            BMP_SIZE = 24
            tsize = (BMP_SIZE, BMP_SIZE)
            self.il = wx.ImageList(BMP_SIZE, BMP_SIZE)
    
            # bitmap generation, uses stock bitmaps included in wxPython
            new_bmp =  wx.ArtProvider.GetBitmap(wx.ART_NEW, wx.ART_TOOLBAR, tsize)
            open_bmp = wx.ArtProvider.GetBitmap(wx.ART_FILE_OPEN, wx.ART_TOOLBAR, tsize)
            copy_bmp = wx.ArtProvider.GetBitmap(wx.ART_COPY, wx.ART_TOOLBAR, tsize)
            paste_bmp= wx.ArtProvider.GetBitmap(wx.ART_PASTE, wx.ART_TOOLBAR, tsize)
    
            self.bmpdict = {1: new_bmp, 2: open_bmp, 3: copy_bmp, 4: paste_bmp}
    
            # mapping wxImageList indices to keys in test_list_data
            self.imglistdict = {}
    
            for idx, bmp in self.bmpdict.iteritems():
                self.imglistdict[idx] = self.il.Add(bmp)
    
            self.listctl = wx.ListCtrl(self, -1,
                                     style=wx.LC_REPORT 
                                     #| wx.BORDER_SUNKEN
                                     | wx.BORDER_NONE
                                     | wx.LC_EDIT_LABELS
                                     | wx.LC_SORT_ASCENDING
                                     #| wx.LC_NO_HEADER
                                     #| wx.LC_VRULES
                                     #| wx.LC_HRULES
                                     #| wx.LC_SINGLE_SEL
                                     )
    
            self.listctl.SetImageList(self.il, wx.IMAGE_LIST_SMALL)
            sizer.Add(self.listctl, 1, wx.EXPAND)
    
            self.PopulateList()
    
            self.SetSizer(sizer)
            self.SetAutoLayout(True)
    
        def PopulateList(self):
            # header creation
            info = wx.ListItem()
            info.m_mask = wx.LIST_MASK_TEXT | wx.LIST_MASK_IMAGE | wx.LIST_MASK_FORMAT
            info.m_image = -1
            info.m_format = 0
            info.m_text = "Artist"
            self.listctl.InsertColumnInfo(0, info)
    
            info.m_text = "Title"
            self.listctl.InsertColumnInfo(1, info)
    
            # ListCtrl data generation
            items = test_list_data.items()
            for key, data in items:
                imglist_idx = self.imglistdict[key]
                index = self.listctl.InsertImageStringItem(key, data[0], imglist_idx)
                self.listctl.SetStringItem(index, 1, data[1])
                self.listctl.SetItemData(index, key)
    
    class listctltest(wx.Frame):
        def __init__(self, *args, **kwds):
            wx.Frame.__init__(self, *args, **kwds)
            self.pnl = TestListCtrlPanel(self, -1)
    
    if __name__ == '__main__':
        app = wx.App(redirect=False)
        frm = listctltest(None, -1, 'title')
        frm.Show()
        app.MainLoop()
    

    You can also have a look at UltimateListCtrl in the demo if this has something you want.

    wx.DataViewListCtrl (wxPython >= 2.9 ) is the most advanced of the builtins and has also the possibility to add icons to a list.

    Not included in this list (because I have no experience in it): ObjectListView.