Search code examples
python-3.xwxpythonlistctrl

wxPython ListCtrl item. SetBackgroundColour doesn't work


I'm using Python3, wxPython 4 on MacBook Air M1, macOS Big Sur. I found the SetBackgroundColour method doesn't work, (but when I call item.SetText("888"), the text has been successfully updated ) Does anyone know the reason? Thanks!

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

class MyPanel(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent)
        self.SetBackgroundColour("white")

        rows = [("Tom", "11"),
                ("Ede", "11"),
                ("Jerry", "10")
                ]
        self.list_ctrl = wx.ListCtrl(self, style=wx.LC_REPORT)
        self.list_ctrl.SetBackgroundColour(wx.Colour(255,246,189,255))
        self.list_ctrl.SetTextColour('black')
        
        self.list_ctrl.InsertColumn(0, "Col1")  
        self.list_ctrl.InsertColumn(1, "Col2")  # Revenue this Q than last Q 

        
        index = 0
        for row in rows:
            self.list_ctrl.InsertStringItem(index, row[0])
            self.list_ctrl.SetStringItem(index, 1, row[1])

            if int(row[1]) <= 10: #current PE is 50% down than 52w high
                item = self.list_ctrl.GetItem(1,1)
                item.SetText("888") # successfully changed
                item.SetBackgroundColour('Blue') #not changed
                self.list_ctrl.SetItem(item)

                print(item.GetText())
                print(item.GetBackgroundColour())

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

class MyFrame(wx.Frame):
    def __init__(self):
        """Constructor"""
        wx.Frame.__init__(self, None, wx.ID_ANY,"test")
        panel = MyPanel(self)
        self.Show()
        
if __name__ == "__main__":
    app = wx.App(False)
    frame = MyFrame()
    app.MainLoop()

Solution

  • I've revisited this because your code does some fiddling about, which I didn't take into consideration.
    I've also addressed the Deprecation warnings you would have been getting.
    In short, access the item via the ListCtrl and use the index.

    import wx
    import wx.lib.mixins.listctrl  as  listmix
    
    class MyPanel(wx.Panel):
        def __init__(self, parent):
            wx.Panel.__init__(self, parent)
            self.SetBackgroundColour("white")
    
            rows = [("Tom", "10"),
                    ("Ede", "11"),
                    ("Jerry", "12"),
                    ("Rolf", "10"),
                    ("Neo", "12")
                    ]
            self.list_ctrl = wx.ListCtrl(self, style=wx.LC_REPORT)
            self.list_ctrl.SetBackgroundColour(wx.Colour(255,246,189,255))
            self.list_ctrl.SetTextColour('black')
            
            self.list_ctrl.InsertColumn(0, "Col1")  
            self.list_ctrl.InsertColumn(1, "Col2")  # Revenue this Q than last Q 
    
            
            index = 0
            for row in rows:
                self.list_ctrl.InsertItem(index, row[0])
                self.list_ctrl.SetItem(index, 1, row[1])
    
                if int(row[1]) <= 10: #current PE is 50% down than 52w high
                    self.list_ctrl.SetItemBackgroundColour(index, 'LightGreen')
    
                index += 1
            
            sizer = wx.BoxSizer(wx.VERTICAL)
            sizer.Add(self.list_ctrl, 0, wx.ALL|wx.EXPAND, 5)
            self.SetSizer(sizer)
            
    
    class MyFrame(wx.Frame):
        def __init__(self):
            """Constructor"""
            wx.Frame.__init__(self, None, wx.ID_ANY,"test")
            panel = MyPanel(self)
            self.Show()
            
    if __name__ == "__main__":
        app = wx.App(False)
        frame = MyFrame()
        app.MainLoop()
    

    enter image description here