How to create a virtual list control (Phoenix)

Keywords : ListCtrl, Virtual, Sort, ListCtrlAutoWidthMixin, ColumnSorterMixin, Highlighted row, Icon, Bitmap, Property, wx.TheClipboard.


Demonstrating :

Tested py3.x, wx4.x and Win10.

Are you ready to use some samples ? ;)

Test, modify, correct, complete, improve and share your discoveries ! (!)


Sample one

img_sample_one.png

   1 # sample_one.py
   2 
   3 import wx
   4 
   5 # class MyFrame
   6 # class MyListCtrl
   7 # class MyApp
   8 
   9 #---------------------------------------------------------------------------
  10 
  11 data = [
  12     ['Noel', 'Louise'],
  13     ['Martin', 'Justine'],
  14     ['Antoine', 'Eloise'],
  15     ['Jenifer', 'Marguerite'],
  16     ['Marc', 'Sophie'],
  17     ['Etienne', 'Edith'],
  18     ['Jhon', 'Doe']
  19     ]
  20 
  21 #---------------------------------------------------------------------------
  22 
  23 class MyFrame(wx.Frame):
  24     def __init__(self, title):
  25         wx.Frame.__init__(self, None, -1,
  26                           title,
  27                           size=(420, 200),
  28                           pos=(400, 448))
  29 
  30         #------------
  31 
  32         self.SetIcon(wx.Icon('icons/wxwin.ico'))
  33         self.SetMinSize((420, 200))
  34 
  35         #------------
  36 
  37         self.listCtrl = MyListCtrl(self, data)
  38 
  39 #---------------------------------------------------------------------------
  40 
  41 class MyListCtrl(wx.ListCtrl):
  42     def __init__(self, parent, data):
  43         wx.ListCtrl.__init__(self, parent, -1,
  44                              style=wx.LC_REPORT |
  45                                    wx.LC_VIRTUAL |
  46                                    wx.LC_HRULES |
  47                                    wx.LC_VRULES)
  48 
  49         #------------
  50 
  51         self.SetBackgroundColour("white")
  52 
  53         #------------
  54 
  55         self.items = data
  56         print("Items :",  self.items)
  57 
  58         #------------
  59 
  60         self.InsertColumn(0, "Firstname")
  61         self.InsertColumn(1, "Surname")
  62 
  63         self.SetColumnWidth(0, 100)  # (0, -2)
  64         self.SetColumnWidth(1, 300)  # (1, -2)
  65 
  66         #------------
  67 
  68         self.SetItemCount(len(data))
  69 
  70     #-----------------------------------------------------------------------
  71 
  72     def OnGetItemText(self, item, col):
  73         """
  74         ...
  75         """
  76 
  77         return data[item][col]
  78 
  79 #---------------------------------------------------------------------------
  80 
  81 class MyApp(wx.App):
  82     def OnInit(self):
  83 
  84         #------------
  85 
  86         frame = MyFrame("Sample one")
  87         self.SetTopWindow(frame)
  88         frame.Show(True)
  89 
  90         return True
  91 
  92 #---------------------------------------------------------------------------
  93 
  94 def main():
  95     app = MyApp(False)
  96     app.MainLoop()
  97 
  98 #---------------------------------------------------------------------------
  99 
 100 if __name__ == "__main__" :
 101     main()


Sample two

img_sample_two.png

   1 # sample_two.py
   2 
   3 import wx
   4 import wx.lib.mixins.listctrl as listmix
   5 
   6 # class MyFrame
   7 # class MyListCtrl
   8 # class MyApp
   9 
  10 #---------------------------------------------------------------------------
  11 
  12 data = [
  13     ['Noel', 'Louise'],
  14     ['Martin', 'Justine'],
  15     ['Antoine', 'Eloise'],
  16     ['Jenifer', 'Marguerite'],
  17     ['Marc', 'Sophie'],
  18     ['Etienne', 'Edith'],
  19     ['Jhon', 'Doe']
  20     ]
  21 
  22 #---------------------------------------------------------------------------
  23 
  24 class MyFrame(wx.Frame):
  25     def __init__(self, title):
  26         wx.Frame.__init__(self, None, -1,
  27                           title,
  28                           size=(420, 200),
  29                           pos=(400, 448))
  30 
  31         #------------
  32 
  33         self.SetIcon(wx.Icon('icons/wxwin.ico'))
  34         self.SetMinSize((420, 200))
  35 
  36         #------------
  37 
  38         self.listCtrl = MyListCtrl(self, data)
  39 
  40 #---------------------------------------------------------------------------
  41 
  42 class MyListCtrl(wx.ListCtrl,
  43                  listmix.ListCtrlAutoWidthMixin):
  44     def __init__(self, parent, data):
  45         wx.ListCtrl.__init__(self, parent, -1,
  46                              style=wx.LC_REPORT |
  47                                    wx.LC_VIRTUAL |
  48                                    wx.LC_HRULES |
  49                                    wx.LC_VRULES)
  50 
  51         #------------
  52 
  53         # Initialize the listCtrl auto width.
  54         listmix.ListCtrlAutoWidthMixin.__init__(self)
  55 
  56         #------------
  57 
  58         self.SetBackgroundColour("pink")
  59 
  60         #------------
  61 
  62         self.items = data
  63         print("Items :",  self.items)
  64 
  65         #------------
  66 
  67         self.InsertColumn(0, "Firstname")
  68         self.InsertColumn(1, "Surname")
  69 
  70         self.SetColumnWidth(0, 100)  # (0, -2)
  71         self.SetColumnWidth(1, 300)  # (1, -2)
  72 
  73         #------------
  74 
  75         self.SetItemCount(len(data))
  76 
  77     #-----------------------------------------------------------------------
  78 
  79     def OnGetItemText(self, item, col):
  80         """
  81         ...
  82         """
  83 
  84         return data[item][col]
  85 
  86 #---------------------------------------------------------------------------
  87 
  88 class MyApp(wx.App):
  89     def OnInit(self):
  90 
  91         #------------
  92 
  93         frame = MyFrame("Sample two (ListCtrlAutoWidthMixin)")
  94         self.SetTopWindow(frame)
  95         frame.Show(True)
  96 
  97         return True
  98 
  99 #---------------------------------------------------------------------------
 100 
 101 def main():
 102     app = MyApp(False)
 103     app.MainLoop()
 104 
 105 #---------------------------------------------------------------------------
 106 
 107 if __name__ == "__main__" :
 108     main()


Sample three

img_sample_three.png

   1 # sample_three.py
   2 
   3 # https://bty.sakura.ne.jp/wp/archives/44#more-44
   4 
   5 import wx
   6 import wx.lib.mixins.listctrl as listmix
   7 
   8 # class MyFrame
   9 # class MyListCtrl
  10 # class MyApp
  11 
  12 #---------------------------------------------------------------------------
  13 
  14 caption = ("ID", "Name", "X", "Y", "Z")
  15 
  16 #---------------------------------------------------------------------------
  17 
  18 data = [
  19     (1, "Noel", 5570, 2638, 2933),
  20     (2, "Martin", 1407, 663, 744),
  21     (3, "Antoine", 1364, 652, 712),
  22     (4, "Jenifer", 2347, 1140, 1208),
  23     (5, "Marc", 1121, 527, 593),
  24     (6, "Etienne", 1198, 575, 623),
  25     (7, "Louise", 2067, 1004, 1063),
  26     (8, "Justine", 2969, 1477, 1492),
  27     (9, "Eloise", 2014, 1001, 1013),
  28     (10, "Marguerite", 2016, 993, 1024),
  29     (11, "Sophie", 7090, 3570, 3520),
  30     (12, "Edith", 6098, 3047, 3051),
  31     (13, "Jacob", 12758, 6354, 6405),
  32     (14, "Nelly", 8880, 4484, 4396),
  33     ]
  34 
  35 #---------------------------------------------------------------------------
  36 
  37 class MyFrame(wx.Frame):
  38     def __init__(self, parent, id):
  39         wx.Frame.__init__(self, parent, id,
  40                           "Sample three (sort list)",
  41                           size=(450, 295))
  42 
  43         #------------
  44 
  45         self.SetIcon(wx.Icon('icons/wxwin.ico'))
  46         self.SetMinSize((450, 295))
  47 
  48         #------------
  49 
  50         self.listCtrl = MyListCtrl(self)
  51 
  52 #---------------------------------------------------------------------------
  53 
  54 class MyListCtrl(wx.ListCtrl,
  55                  listmix.ListCtrlAutoWidthMixin):
  56 
  57     flg_sort = "up"
  58 
  59     def __init__(self, parent):
  60         wx.ListCtrl.__init__(self, parent, -1,
  61                              style=wx.LC_REPORT |
  62                                    wx.LC_VIRTUAL |
  63                                    wx.LC_HRULES |
  64                                    wx.LC_VRULES)
  65 
  66         #------------
  67 
  68         # Initialize the listCtrl auto width.
  69         listmix.ListCtrlAutoWidthMixin.__init__(self)
  70 
  71         #------------
  72 
  73         self.SetBackgroundColour("#c8c8c8")
  74 
  75         #------------
  76 
  77         self.items = data
  78         print("Items :",  self.items)
  79 
  80         #------------
  81 
  82         self.InsertColumn(0, caption[0], wx.LIST_FORMAT_RIGHT)
  83         self.InsertColumn(1, caption[1], wx.LIST_FORMAT_LEFT)
  84         self.InsertColumn(2, caption[2], wx.LIST_FORMAT_RIGHT)
  85         self.InsertColumn(3, caption[3], wx.LIST_FORMAT_RIGHT)
  86         self.InsertColumn(4, caption[4], wx.LIST_FORMAT_RIGHT)
  87 
  88         #------------
  89 
  90         self.SetItemCount(len(self.items))
  91 
  92         #------------
  93 
  94         self.Bind(wx.EVT_LIST_COL_CLICK, self.Sort)
  95 
  96     #-----------------------------------------------------------------------
  97 
  98     def OnGetItemText(self, item, col):
  99         """
 100         ...
 101         """
 102 
 103         items = (self.items[item][col])
 104 
 105         return str(items)
 106 
 107 
 108     def Sort(self, event):
 109         """
 110         ...
 111         """
 112 
 113         col = event.GetColumn()
 114 
 115         #------------
 116 
 117         if self.flg_sort == "up":
 118             self.items.sort(key=lambda x: x[col])
 119             self.flg_sort = "down"
 120         else:
 121             self.items.sort(key=lambda x: x[col])
 122             self.items.reverse()
 123             self.flg_sort = "up"
 124 
 125         #------------
 126 
 127         self.DeleteAllItems()
 128 
 129         #------------
 130 
 131         self.SetItemCount(len(self.items))
 132 
 133 #---------------------------------------------------------------------------
 134 
 135 class MyApp(wx.App):
 136     def OnInit(self):
 137 
 138         #------------
 139 
 140         frame = MyFrame(parent=None, id=-1)
 141         self.SetTopWindow(frame)
 142         frame.Show(True)
 143 
 144         return True
 145 
 146 #---------------------------------------------------------------------------
 147 
 148 def main():
 149     app = MyApp(False)
 150     app.MainLoop()
 151 
 152 #---------------------------------------------------------------------------
 153 
 154 if __name__ == "__main__" :
 155     main()


Sample four

img_sample_four.png

   1 # sample_four.py
   2 
   3 # https://bty.sakura.ne.jp/wp/archives/51
   4 
   5 import wx
   6 import wx.lib.mixins.listctrl as listmix
   7 
   8 # class MyFrame
   9 # class MyListCtrl
  10 # class MyApp
  11 
  12 #---------------------------------------------------------------------------
  13 
  14 caption = ("ID", "Name", "X", "Y", "Z")
  15 
  16 #---------------------------------------------------------------------------
  17 
  18 data = [
  19     (1, "Noel", 5570, 2638, 2933),
  20     (2, "Martin", 1407, 663, 744),
  21     (3, "Antoine", 1364, 652, 712),
  22     (4, "Jenifer", 2347, 1140, 1208),
  23     (5, "Marc", 1121, 527, 593),
  24     (6, "Etienne", 1198, 575, 623),
  25     (7, "Louise", 2067, 1004, 1063),
  26     (8, "Justine", 2969, 1477, 1492),
  27     (9, "Eloise", 2014, 1001, 1013),
  28     (10, "Marguerite", 2016, 993, 1024),
  29     (11, "Sophie", 7090, 3570, 3520),
  30     (12, "Edith", 6098, 3047, 3051),
  31     (13, "Jacob", 12758, 6354, 6405),
  32     (14, "Nelly", 8880, 4484, 4396),
  33     ]
  34 
  35 #---------------------------------------------------------------------------
  36 
  37 class MyFrame(wx.Frame):
  38     def __init__(self, parent, id):
  39         wx.Frame.__init__(self, parent, id,
  40                           "Sample four (sort list)",
  41                           size=(450, 295))
  42 
  43         #------------
  44 
  45         self.SetIcon(wx.Icon('icons/wxwin.ico'))
  46         self.SetMinSize((450, 295))
  47 
  48         #------------
  49 
  50         self.listCtrl = MyListCtrl(self)
  51 
  52 #---------------------------------------------------------------------------
  53 
  54 class MyListCtrl(wx.ListCtrl,
  55                  listmix.ListCtrlAutoWidthMixin):
  56     def __init__(self, parent):
  57         wx.ListCtrl.__init__(self, parent, -1,
  58                              style=wx.LC_REPORT |
  59                                    wx.LC_VIRTUAL |
  60                                    wx.LC_HRULES |
  61                                    wx.LC_VRULES)
  62 
  63         #------------
  64 
  65         # Initialize the listCtrl auto width.
  66         listmix.ListCtrlAutoWidthMixin.__init__(self)
  67 
  68         #------------
  69 
  70         self.prevColumn = False
  71         self.sortAcend = True
  72 
  73         #------------
  74 
  75         self.SetBackgroundColour("#94e6ff")
  76 
  77         #------------
  78 
  79         self.items = data
  80         print("Items :",  self.items)
  81 
  82         #------------
  83 
  84         self.InsertColumn(0, caption[0], wx.LIST_FORMAT_RIGHT)
  85         self.InsertColumn(1, caption[1], wx.LIST_FORMAT_LEFT)
  86         self.InsertColumn(2, caption[2], wx.LIST_FORMAT_RIGHT)
  87         self.InsertColumn(3, caption[3], wx.LIST_FORMAT_RIGHT)
  88         self.InsertColumn(4, caption[4], wx.LIST_FORMAT_RIGHT)
  89 
  90         #------------
  91 
  92         self.SetItemCount(len(self.items))
  93 
  94         #------------
  95 
  96         self.Bind(wx.EVT_LIST_COL_CLICK, self.Sort)
  97 
  98     #-----------------------------------------------------------------------
  99 
 100     def GetListCtrl(self):
 101         """
 102         ...
 103         """
 104 
 105         return self
 106 
 107 
 108     def OnGetItemText(self, item, col):
 109         """
 110         ...
 111         """
 112 
 113         items = (self.items[item][col])
 114 
 115         return str(items)
 116 
 117 
 118     def Sort(self, event):
 119         """
 120         ...
 121         """
 122 
 123         col = event.GetColumn()
 124 
 125         #------------
 126 
 127         if col != self.prevColumn:
 128             self.sortAcend = True
 129         else:
 130             if self.sortAcend:
 131                 self.sortAcend = None
 132             else:
 133                 self.sortAcend = True
 134         if self.sortAcend:
 135             self.items.sort(key=lambda x: x[col])
 136         else:
 137             self.items.reverse()
 138 
 139         self.prevColumn = col
 140 
 141         #------------
 142 
 143         self.DeleteAllItems()
 144 
 145         #------------
 146 
 147         self.SetItemCount(len(self.items))
 148 
 149 #---------------------------------------------------------------------------
 150 
 151 class MyApp(wx.App):
 152     def OnInit(self):
 153 
 154         #------------
 155 
 156         frame = MyFrame(parent=None, id=-1)
 157         self.SetTopWindow(frame)
 158         frame.Show(True)
 159 
 160         return True
 161 
 162 #---------------------------------------------------------------------------
 163 
 164 def main():
 165     app = MyApp(False)
 166     app.MainLoop()
 167 
 168 #---------------------------------------------------------------------------
 169 
 170 if __name__ == "__main__" :
 171     main()


Sample five

img_sample_five.png

   1 # sample_five.py
   2 
   3 # http://bty.sakura.ne.jp/wp/archives/52
   4 
   5 import wx
   6 import wx.lib.mixins.listctrl as listmix
   7 
   8 # class MyFrame
   9 # class MyListCtrl
  10 # class MyApp
  11 
  12 #---------------------------------------------------------------------------
  13 
  14 caption = ("ID", "Name", "X", "Y", "Z")
  15 
  16 #---------------------------------------------------------------------------
  17 
  18 data = [
  19     (1, "Noel", 5570, 2638, 2933),
  20     (2, "Martin", 1407, 663, 744),
  21     (3, "Antoine", 1364, 652, 712),
  22     (4, "Jenifer", 2347, 1140, 1208),
  23     (5, "Marc", 1121, 527, 593),
  24     (6, "Etienne", 1198, 575, 623),
  25     (7, "Louise", 2067, 1004, 1063),
  26     (8, "Justine", 2969, 1477, 1492),
  27     (9, "Eloise", 2014, 1001, 1013),
  28     (10, "Marguerite", 2016, 993, 1024),
  29     (11, "Sophie", 7090, 3570, 3520),
  30     (12, "Edith", 6098, 3047, 3051),
  31     (13, "Jacob", 12758, 6354, 6405),
  32     (14, "Nelly", 8880, 4484, 4396),
  33     ]
  34 
  35 #---------------------------------------------------------------------------
  36 
  37 class MyFrame(wx.Frame):
  38     def __init__(self, parent, id):
  39         wx.Frame.__init__(self, parent, id,
  40                           "Sample five (copy to wx.TheClipboard & sort list)",
  41                           size=(450, 300))
  42 
  43         #------------
  44 
  45         self.SetIcon(wx.Icon('icons/wxwin.ico'))
  46         self.SetMinSize((450, 300))
  47 
  48         #------------
  49 
  50         self.panel = wx.Panel(self, -1)
  51         self.btnCopy = wx.Button(self.panel, -1, "Copy")
  52         self.Bind(wx.EVT_BUTTON, self.OnBtnCopy, self.btnCopy)
  53 
  54         self.listCtrl = MyListCtrl(self.panel)
  55 
  56         #------------
  57 
  58         mainSizer = wx.BoxSizer(wx.VERTICAL)
  59         btnSizer = wx.BoxSizer(wx.HORIZONTAL)
  60 
  61         btnSizer.Add(self.btnCopy, 1)
  62 
  63         mainSizer.Add(btnSizer, 0, wx.EXPAND)
  64         mainSizer.Add(self.listCtrl, 1, wx.EXPAND)
  65 
  66         self.panel.SetSizer(mainSizer)
  67 
  68     #-----------------------------------------------------------------------
  69 
  70     def OnBtnCopy(self, event):
  71         """
  72         ...
  73         """
  74 
  75         if not wx.TheClipboard.Open():
  76             wx.MessageBox("Unable to copy to clipboard !")
  77             return
  78 
  79         text = ""
  80         for i in range(self.listCtrl.GetItemCount()):
  81             item = self.listCtrl.GetItem(i)
  82             if item.GetState() & wx.LIST_STATE_SELECTED:
  83                 d = self.listCtrl.items[i]
  84                 text += str(d[0])+' '+d[1]+' '+str(d[2])+' '+str(d[3])+' '+str(d[4])+'\r\n'
  85                 print("Copy to wx.TheClipboard :", text)
  86 
  87         do = wx.TextDataObject(text)
  88         wx.TheClipboard.SetData(do)
  89         wx.TheClipboard.Close()
  90 
  91 #---------------------------------------------------------------------------
  92 
  93 class MyListCtrl(wx.ListCtrl,
  94                  listmix.ListCtrlAutoWidthMixin):
  95     def __init__(self, parent):
  96         wx.ListCtrl.__init__(self, parent, -1,
  97                              style=wx.LC_REPORT |
  98                                    wx.LC_VIRTUAL |
  99                                    wx.LC_HRULES |
 100                                    wx.LC_VRULES)
 101 
 102         #------------
 103 
 104         # Initialize the listCtrl auto width.
 105         listmix.ListCtrlAutoWidthMixin.__init__(self)
 106 
 107         #------------
 108 
 109         self.prevColumn = False
 110         self.sortAcend = True
 111 
 112         #------------
 113 
 114         self.SetBackgroundColour("#ffbb55")
 115 
 116         #------------
 117 
 118         self.items = data
 119         print("Items :",  self.items)
 120 
 121         #------------
 122 
 123         self.InsertColumn(0, caption[0], wx.LIST_FORMAT_RIGHT)
 124         self.InsertColumn(1, caption[1], wx.LIST_FORMAT_LEFT)
 125         self.InsertColumn(2, caption[2], wx.LIST_FORMAT_RIGHT)
 126         self.InsertColumn(3, caption[3], wx.LIST_FORMAT_RIGHT)
 127         self.InsertColumn(4, caption[4], wx.LIST_FORMAT_RIGHT)
 128 
 129         #------------
 130 
 131         self.SetItemCount(len(self.items))
 132 
 133         #------------
 134 
 135         self.Bind(wx.EVT_LIST_COL_CLICK, self.Sort)
 136 
 137     #-----------------------------------------------------------------------
 138 
 139     def GetListCtrl(self):
 140         """
 141         ...
 142         """
 143 
 144         return self
 145 
 146 
 147     def OnGetItemText(self, item, col):
 148         """
 149         ...
 150         """
 151 
 152         items = (self.items[item][col])
 153 
 154         return str(items)
 155 
 156 
 157     def Sort(self, event):
 158         """
 159         ...
 160         """
 161 
 162         col = event.GetColumn()
 163 
 164         #------------
 165 
 166         if col != self.prevColumn:
 167             self.sortAcend = True
 168         else:
 169             if self.sortAcend:
 170                 self.sortAcend = None
 171             else:
 172                 self.sortAcend = True
 173         if self.sortAcend:
 174             self.items.sort(key=lambda x: x[col])
 175         else:
 176             self.items.reverse()
 177 
 178         self.prevColumn = col
 179 
 180         #------------
 181 
 182         self.DeleteAllItems()
 183 
 184         #------------
 185 
 186         self.SetItemCount(len(self.items))
 187 
 188 #---------------------------------------------------------------------------
 189 
 190 class MyApp(wx.App):
 191     def OnInit(self):
 192 
 193         #------------
 194 
 195         frame = MyFrame(parent=None, id=-1)
 196         self.SetTopWindow(frame)
 197         frame.Show(True)
 198 
 199         return True
 200 
 201 #---------------------------------------------------------------------------
 202 
 203 def main():
 204     app = MyApp(False)
 205     app.MainLoop()
 206 
 207 #---------------------------------------------------------------------------
 208 
 209 if __name__ == "__main__" :
 210     main()


Sample six

img_sample_six.png

   1 # sample_six.py
   2 
   3 import wx
   4 import wx.lib.mixins.listctrl as listmix
   5 
   6 # class MyFrame
   7 # class MyListCtrl
   8 # class MyApp
   9 
  10 #---------------------------------------------------------------------------
  11 
  12 data = [
  13     ['Noel', 'Louise'],
  14     ['Martin', 'Justine'],
  15     ['Antoine', 'Eloise'],
  16     ['Jenifer', 'Marguerite'],
  17     ['Marc', 'Sophie'],
  18     ['Etienne', 'Edith'],
  19     ['Jhon', 'Doe']
  20     ]
  21 
  22 #---------------------------------------------------------------------------
  23 
  24 class MyFrame(wx.Frame):
  25     def __init__(self, title):
  26         wx.Frame.__init__(self, None, -1,
  27                           title,
  28                           size=(420, 200),
  29                           pos=(400, 448))
  30 
  31         #------------
  32 
  33         self.SetIcon(wx.Icon('icons/wxwin.ico'))
  34         self.SetMinSize((420, 200))
  35 
  36         #------------
  37 
  38         self.listCtrl = MyListCtrl(self, data)
  39 
  40 #---------------------------------------------------------------------------
  41 
  42 class MyListCtrl(wx.ListCtrl,
  43                  listmix.ListCtrlAutoWidthMixin):
  44     def __init__(self, parent, data):
  45         wx.ListCtrl.__init__(self, parent, -1,
  46                              style=wx.LC_REPORT |
  47                                    wx.LC_VIRTUAL |
  48                                    wx.LC_HRULES |
  49                                    wx.LC_VRULES)
  50 
  51         #------------
  52 
  53         # Initialize the listCtrl auto width.
  54         listmix.ListCtrlAutoWidthMixin.__init__(self)
  55 
  56         #------------
  57 
  58         self.prevColumn = False
  59         self.sortAcend = True
  60 
  61         #------------
  62 
  63         self.attr1 = wx.ItemAttr()
  64         self.attr1.SetBackgroundColour("#e6ffd0")
  65 
  66         self.attr2 = wx.ItemAttr()
  67         self.attr2.SetBackgroundColour("#f0f0f0")
  68 
  69         self.attr3 = wx.ItemAttr()
  70         self.attr3.SetBackgroundColour("#fffccc")
  71 
  72         #------------
  73 
  74         self.items = data
  75         print("Items :",  self.items)
  76 
  77         #------------
  78 
  79         self.InsertColumn(0, "Firstname")
  80         self.InsertColumn(1, "Surname")
  81 
  82         self.SetColumnWidth(0, 100)  # (0, -2)
  83         self.SetColumnWidth(1, 300)  # (1, -2)
  84 
  85         #------------
  86 
  87         self.SetItemCount(len(data))
  88 
  89         #------------
  90 
  91         self.Bind(wx.EVT_LIST_COL_CLICK, self.Sort)
  92 
  93     #-----------------------------------------------------------------------
  94 
  95     def OnGetItemText(self, item, col):
  96         """
  97         ...
  98         """
  99 
 100         return data[item][col]
 101 
 102 
 103     def OnGetItemAttr(self, item):
 104         """
 105         ...
 106         """
 107 
 108         if item % 4 == 0:
 109             return self.attr1
 110         elif item % 4 == 1:
 111             return self.attr2
 112         elif item % 4 == 2:
 113             return self.attr3
 114         else:
 115             return None
 116 
 117 
 118     def Sort(self, event):
 119         """
 120         ...
 121         """
 122 
 123         col = event.GetColumn()
 124 
 125         #------------
 126 
 127         if col != self.prevColumn:
 128             self.sortAcend = True
 129         else:
 130             if self.sortAcend:
 131                 self.sortAcend = None
 132             else:
 133                 self.sortAcend = True
 134         if self.sortAcend:
 135             self.items.sort(key=lambda x: x[col])
 136         else:
 137             self.items.reverse()
 138 
 139         self.prevColumn = col
 140 
 141         #------------
 142 
 143         self.DeleteAllItems()
 144 
 145         #------------
 146 
 147         self.SetItemCount(len(self.items))
 148 
 149 #---------------------------------------------------------------------------
 150 
 151 class MyApp(wx.App):
 152     def OnInit(self):
 153 
 154         #------------
 155 
 156         frame = MyFrame("Sample six (highlighted row)")
 157         self.SetTopWindow(frame)
 158         frame.Show(True)
 159 
 160         return True
 161 
 162 #---------------------------------------------------------------------------
 163 
 164 def main():
 165     app = MyApp(False)
 166     app.MainLoop()
 167 
 168 #---------------------------------------------------------------------------
 169 
 170 if __name__ == "__main__" :
 171     main()


Sample seven

img_sample_seven.png

   1 # sample_seven.py
   2 
   3 import wx
   4 import wx.lib.mixins.listctrl as listmix
   5 
   6 # class MyFrame
   7 # class MyListCtrl
   8 # class MyApp
   9 
  10 #---------------------------------------------------------------------------
  11 
  12 caption = ("ID", "Name", "X", "Y", "Z")
  13 
  14 #---------------------------------------------------------------------------
  15 
  16 data = [
  17     (1, "Noel", 5570, 2638, 2933),
  18     (2, "Martin", 1407, 663, 744),
  19     (3, "Antoine", 1364, 652, 712),
  20     (4, "Jenifer", 2347, 1140, 1208),
  21     (5, "Marc", 1121, 527, 593),
  22     (6, "Etienne", 1198, 575, 623),
  23     (7, "Louise", 2067, 1004, 1063),
  24     (8, "Justine", 2969, 1477, 1492),
  25     (9, "Eloise", 2014, 1001, 1013),
  26     (10, "Marguerite", 2016, 993, 1024),
  27     (11, "Sophie", 7090, 3570, 3520),
  28     (12, "Edith", 6098, 3047, 3051),
  29     (13, "Jacob", 12758, 6354, 6405),
  30     (14, "Nelly", 8880, 4484, 4396),
  31     ]
  32 
  33 #---------------------------------------------------------------------------
  34 
  35 class MyFrame(wx.Frame):
  36     def __init__(self, parent, id):
  37         wx.Frame.__init__(self, parent, id,
  38                           "Sample seven (popup menu)",
  39                           size=(450, 295))
  40 
  41         #------------
  42 
  43         self.SetIcon(wx.Icon('icons/wxwin.ico'))
  44         self.SetMinSize((450, 295))
  45 
  46         #------------
  47 
  48         self.listCtrl = MyListCtrl(self)
  49 
  50 #---------------------------------------------------------------------------
  51 
  52 class MyListCtrl(wx.ListCtrl,
  53                  listmix.ListCtrlAutoWidthMixin):
  54     def __init__(self, parent):
  55         wx.ListCtrl.__init__(self, parent, -1,
  56                              style=wx.LC_REPORT |
  57                                    wx.LC_VIRTUAL |
  58                                    wx.LC_HRULES |
  59                                    wx.LC_VRULES)
  60 
  61         #------------
  62 
  63         # Initialize the listCtrl auto width.
  64         listmix.ListCtrlAutoWidthMixin.__init__(self)
  65 
  66         #------------
  67 
  68         self.prevColumn = False
  69         self.sortAcend = True
  70 
  71         #------------
  72 
  73         self.SetBackgroundColour("#8be587")
  74 
  75         #------------
  76 
  77         self.items = data
  78         print("Items :",  self.items)
  79 
  80         #------------
  81 
  82         self.InsertColumn(0, caption[0], wx.LIST_FORMAT_RIGHT)
  83         self.InsertColumn(1, caption[1], wx.LIST_FORMAT_LEFT)
  84         self.InsertColumn(2, caption[2], wx.LIST_FORMAT_RIGHT)
  85         self.InsertColumn(3, caption[3], wx.LIST_FORMAT_RIGHT)
  86         self.InsertColumn(4, caption[4], wx.LIST_FORMAT_RIGHT)
  87 
  88         #------------
  89 
  90         self.SetItemCount(len(self.items))
  91 
  92         #------------
  93 
  94         self.Bind(wx.EVT_LIST_COL_CLICK, self.Sort)
  95 
  96         #------------
  97 
  98         # For wxMSW.
  99         self.Bind(wx.EVT_COMMAND_RIGHT_CLICK, self.OnRightClick)
 100 
 101         # For wxGTK.
 102         self.Bind(wx.EVT_RIGHT_UP, self.OnRightClick)
 103 
 104     #-----------------------------------------------------------------------
 105 
 106     def OnRightClick(self, event):
 107         """
 108         ...
 109         """
 110 
 111         # Only do this part the first time
 112         # so the events are only bound once.
 113         if not hasattr(self, "popupID1"):
 114             self.popupID1 = wx.NewIdRef()
 115             self.popupID2 = wx.NewIdRef()
 116             self.popupID3 = wx.NewIdRef()
 117 
 118             self.Bind(wx.EVT_MENU, self.OnPopupOne, id=self.popupID1)
 119             self.Bind(wx.EVT_MENU, self.OnPopupTwo, id=self.popupID2)
 120             self.Bind(wx.EVT_MENU, self.OnPopupThree, id=self.popupID3)
 121 
 122         #------------
 123 
 124         # Make a menu.
 125         menu = wx.Menu()
 126 
 127         # Add some items.
 128         menu.Append(self.popupID1, "First message box")
 129         menu.Append(self.popupID2, "Second message box")
 130         menu.Append(self.popupID3, "Delete all items")
 131 
 132         # Popup the menu.  If an item is selected then its
 133         # handler will be called before PopupMenu returns.
 134         self.PopupMenu(menu)
 135         menu.Destroy()
 136 
 137 
 138     def OnPopupOne(self, event):
 139         """
 140         ...
 141         """
 142 
 143         dlg = wx.MessageDialog(self,
 144                                "Hello from Python and wxPython !",
 145                                "First message box",
 146                                wx.OK | wx.ICON_INFORMATION)
 147         dlg.ShowModal()
 148         dlg.Destroy()
 149 
 150 
 151     def OnPopupTwo(self, event):
 152         """
 153         ...
 154         """
 155 
 156         dlg = wx.MessageDialog(self,
 157                                "Welcome !",
 158                                "Second message box",
 159                                wx.OK | wx.ICON_INFORMATION)
 160         dlg.ShowModal()
 161         dlg.Destroy()
 162 
 163 
 164     def OnPopupThree(self, event):
 165         """
 166         ...
 167         """
 168 
 169         self.DeleteAllItems()
 170 
 171 
 172     def GetListCtrl(self):
 173         """
 174         ...
 175         """
 176 
 177         return self
 178 
 179 
 180     def OnGetItemText(self, item, col):
 181         """
 182         ...
 183         """
 184 
 185         items = (self.items[item][col])
 186 
 187         return str(items)
 188 
 189 
 190     def Sort(self, event):
 191         """
 192         ...
 193         """
 194 
 195         col = event.GetColumn()
 196 
 197         #------------
 198 
 199         if col != self.prevColumn:
 200             self.sortAcend = True
 201         else:
 202             if self.sortAcend:
 203                 self.sortAcend = None
 204             else:
 205                 self.sortAcend = True
 206         if self.sortAcend:
 207             self.items.sort(key=lambda x: x[col])
 208         else:
 209             self.items.reverse()
 210 
 211         self.prevColumn = col
 212 
 213         #------------
 214 
 215         self.DeleteAllItems()
 216 
 217         #------------
 218 
 219         self.SetItemCount(len(self.items))
 220 
 221 #---------------------------------------------------------------------------
 222 
 223 class MyApp(wx.App):
 224     def OnInit(self):
 225 
 226         #------------
 227 
 228         frame = MyFrame(parent=None, id=-1)
 229         self.SetTopWindow(frame)
 230         frame.Show(True)
 231 
 232         return True
 233 
 234 #---------------------------------------------------------------------------
 235 
 236 def main():
 237     app = MyApp(False)
 238     app.MainLoop()
 239 
 240 #---------------------------------------------------------------------------
 241 
 242 if __name__ == "__main__" :
 243     main()


Sample eight

img_sample_eight.png

   1 # sample_eight.py
   2 
   3 """
   4 
   5 Author(s)  : ???
   6              Modified and updated for wxPython Phoenix by Ecco
   7 Version    : 0.0.2
   8 Website    : Python-it.org
   9 
  10 """
  11 
  12 import wx
  13 import wx.lib.mixins.listctrl as listmix
  14 
  15 # class MyDataSource
  16 # class MyDefaultItemAttr
  17 # class MyProperty
  18 # class MyListCtrl
  19 # class MyFrame
  20 # class MyApp
  21 
  22 #---------------------------------------------------------------------------
  23 
  24 class MyDataSource(object):
  25     """
  26     Questa classe acquisiscie i dati da visualizzare nel wx.ListCtrl Virtuale.
  27     Per il suo corretto funzionamento i dati devono provenire da :
  28         - una lista per le intestazioni delle colonne;
  29         - una lista di liste, per le righe.
  30     I parametri passati all'__init__ sono :
  31         col per le intestazioni delle colonne;
  32         row per le righe.
  33 
  34     #------------
  35 
  36     Cette classe acquiere les donnees a afficher dans la wx.ListCtrl virtuelle.
  37     Pour un fonctionnement correct, les donnees doivent provenir de :
  38         - Une liste pour les en-tetes de colonnes;
  39         - Une liste des listes, pour les lignes.
  40     Les parametres passes a __init__ sont :
  41         col pour les en-tetes de colonnes;
  42         row pour les lignes.
  43     """
  44 
  45     def __init__(self, col, row):
  46         """
  47         ...
  48         """
  49 
  50         self.col = col
  51         self.row = row
  52 
  53     #-----------------------------------------------------------------------
  54 
  55     def GetColumnHeaders(self):
  56         """
  57         Ritorna la lista delle Colonne.
  58         Retourne la liste des colonnes.
  59         """
  60 
  61         return self.col
  62 
  63 
  64     def GetCount(self):
  65         """
  66         Ritorna il numero delle Righe.
  67         Retourne le nombre de rangees.
  68         """
  69 
  70         return len(self.row)
  71 
  72 
  73     def GetColCount(self):
  74         """
  75         Ritorna il numero delle Colonne.
  76         Retourne le nombre de colonnes.
  77         """
  78 
  79         return len(self.col)
  80 
  81 
  82     def GetItem(self, index):
  83         """
  84         Ritorna il valore della cella passato ad index.
  85         Retourne la valeur de la cellule transmise a l'index.
  86         """
  87 
  88         return self.row[index]
  89 
  90 
  91     def UpdateCache(self, start, end):
  92         pass
  93 
  94 #---------------------------------------------------------------------------
  95 
  96 class MyDefaultItemAttr(object):
  97     """
  98     Questa e' una classe di comodo per l'assegnazione dei valori di default
  99     dei tre attributi Font, BackgroundColour, TextColour.
 100 
 101     #------------
 102 
 103     C'est une  classe de commodite pour l'attribution des valeurs par defaut
 104     de ces trois attributs Font, BackgroundColour, TextColour.
 105     """
 106 
 107     default_font = (8, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL)
 108     default_BackgroundColour = "white"
 109     default_TextColour = "black"
 110 
 111     default_itemAttr = [default_font, default_BackgroundColour, default_TextColour]
 112 
 113 #---------------------------------------------------------------------------
 114 
 115 class MyProperty(object):
 116     """
 117     Questa classe fornisce le varie proprieta' al wx.ListCtrl Virtuale :
 118         width e' una lista di valori per la larghezza delle colonne, valore di Default ==> [-1];
 119         align e' una lista di valori per l'allinemento delle colonne, valore di Default ==> [wx.LIST_FORMAT_LEFT];
 120         itemAttr e' una lista di valori per gli Attributi di Riga,
 121             permette la creazione di tanti wx.ItemAttr per ogni elemente presente nella lista,
 122             ogni singolo elemento e' composto a sua volta da tre valori, rispettivamente per il Font, per il BackgroundColour e il TextColour
 123             valore di Default ==> [(8, wx.FONTFAMILY_DEFAULT  , wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL), "white", "black"]
 124 
 125         L'__init__ prende un parametro :
 126             property che e' un dizionario con le proprieta' su elencate i cui indici sono le proprieta' stesse.
 127 
 128     #------------
 129 
 130      Cette classe fournie diverses proprietes a la wx.ListCtrl virtuelle :
 131         width est une liste de valeurs pour la largeur des colonnes, valeur par defaut ==> [-1];
 132         align est une liste de valeurs pour l'alignement des colonnes, valeur par defaut, ==> [wx.LIST_FORMAT_LEFT];
 133         itemAttr et une liste de valeurs pour les attributs de Riga,
 134             permet la creation de nombreux wx.ItemAttr pour chaque element present dans la liste,
 135             chaque element individuel est constitue a son tour par trois valeurs, respectivement pour Font, pour BackgroundColour et TextColour
 136             La valeur par defaut ==> [(8, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL), "white", "black"]
 137 
 138         La methode __ init__ prend un parametre :
 139             la propriete est un dictionnaire avec les proprietes dont les indices ont des proprietes qui leur sont propre.
 140     """
 141 
 142     def __init__(self, property):
 143         """
 144         ...
 145         """
 146 
 147         self.property = property
 148 
 149         self.default_font = MyDefaultItemAttr().default_itemAttr
 150         self.default_BackgroundColour = MyDefaultItemAttr().default_BackgroundColour
 151         self.default_TextColour = MyDefaultItemAttr().default_TextColour
 152         self.default_itemAttr = MyDefaultItemAttr().default_itemAttr
 153 
 154     #-----------------------------------------------------------------------
 155 
 156     def get_property(self):
 157         """
 158         Restituisce il dizionario con le propriea' del wx.ListCtrl Virtuale.
 159         Retourne le dictionnaire avec les proprietes de la wx.ListCtrl virtuelle.
 160         """
 161 
 162         return {
 163                 "width": self._get_width(),
 164                 "align": self._get_align(),
 165                 "itemAttr": self._get_itemAttr()
 166                }
 167 
 168 
 169     def _get_property(self, index, default):
 170         """
 171         Metodo interno di comodo per il vari get_*.
 172         Se index non e' presente nel dizionario fa ritornare il valore di Default.
 173 
 174         Methode interne de commodite pour les differents get_*.
 175         Si l'index n'est pas present dans le dictionnaire il retourne la valeur par defaut.
 176         """
 177 
 178         if not self.property.get(index, False):
 179             return default
 180         else:
 181             return self.property[index]
 182 
 183 
 184     #--- Metodi per assegnare i valori alle proprieta'.
 185     #--- Methodes pour attribuer des valeurs a la propriete.
 186     def _get_width(self):
 187         """
 188         Ritorna il valore di width.
 189         Retourne la valeur de la largeur.
 190         """
 191 
 192         return self._get_property("width", [-1])
 193 
 194 
 195     def _get_align(self):
 196         """
 197         Ritorna il valore di align.
 198         Retourne la valeur de l'alignement.
 199         """
 200 
 201         return self._get_property("align", [wx.LIST_FORMAT_LEFT])
 202 
 203 
 204     def _get_itemAttr(self):
 205         """
 206         Ritorna una lista di wx.ItemAttr per Font, Colore Sfondo e Colore Testo
 207         Se uno o piu' valori non sono presenti assegna quello di default.
 208 
 209         Retourne une liste des wx.ItemAttr pour la Font, le BackgroundColour et le ForegroundColour du texte
 210         Si une ou plusieurs valeurs ne sont pas presentes il attribue la valeur par defaut.
 211         """
 212 
 213         def _assign_value(list1, list2):
 214             attr = wx.ItemAttr()
 215             try: attr.SetFont(wx.Font(*list1[0]))
 216             except IndexError and TypeError: attr.SetFont(wx.Font(*list2[0]))
 217 
 218             try: attr.SetBackgroundColour(list1[1])
 219             except IndexError: attr.SetBackgroundColour(list2[1])
 220 
 221             try: attr.SetTextColour(list1[2])
 222             except IndexError: attr.SetTextColour(list2[2])
 223 
 224             return attr
 225 
 226         list_attr = []
 227         for l in self.property.get("itemAttr", [self.default_itemAttr]):
 228             list_attr.append(_assign_value(l, self.default_itemAttr))
 229 
 230         return list_attr
 231 
 232 #---------------------------------------------------------------------------
 233 
 234 class MyListCtrl(wx.ListCtrl,
 235                  listmix.ListCtrlAutoWidthMixin,
 236                  listmix.ColumnSorterMixin):
 237     """
 238     Questa classe e' il cuore pulsante di MyListCtrl.
 239     L'__init__ richiede due parametri:
 240         dataSource che e' la lista dei valori da visualizzare nella lista;
 241         property che e' il dizionario delle proprieta' della lista, questo parametro e' facoltativo.
 242 
 243     #------------
 244 
 245     Cette classe et le cœur de MyListCtrl.
 246     La methode __ init__ requiert deux parametres:
 247         dataSource est la liste des valeurs a afficher dans la liste;
 248         property et le dictionnaire de la liste des proprietes, ce parametre est optionnel.
 249     """
 250 
 251     def __init__(self, *args, **kwargs):
 252 
 253         self.dataSource = kwargs.pop("dataSource")
 254 
 255         #--- Se property non viene dichiarato ne viene ritornato uno vuoto.
 256         #--- Si la propriete n'est pas declaree, elle est renvoyee a vide.
 257         try:property = kwargs.pop("property")
 258         except KeyError: property=MyProperty({})
 259 
 260         #---
 261 
 262         wx.ListCtrl.__init__(self,
 263                              style=wx.LC_REPORT |
 264                                    wx.LC_VIRTUAL |
 265                                    wx.LC_SINGLE_SEL |
 266                                    wx.LC_VRULES |
 267                                    wx.LC_HRULES,
 268                              *args, **kwargs)
 269 
 270         #------------
 271 
 272         # Initialize the listCtrl auto width.
 273         listmix.ListCtrlAutoWidthMixin.__init__(self)
 274 
 275         #------------
 276 
 277         self.prevColumn = None
 278         self.sortAcend = False
 279 
 280         #------------
 281 
 282         # Larghezza colonne.
 283         # Largeur de colonne.
 284         width = property.get_property()["width"]
 285         # Allineamento colonne.
 286         # Alignement de colonne.
 287         align = property.get_property()["align"]
 288         # Attributi righe.
 289         # Attributs de lignes.
 290         self.itemAttr = property.get_property()["itemAttr"]
 291 
 292         #--- Crea le colonne :
 293         #--- Creation de colonnes :
 294         #    Se le liste non sono complete per tutte le colonne passa i parametri alle prime n colonne.
 295         #    per le restanti passa i valori di Default, wx.LIST_FORMAT_LEFT per align e -1 per width.
 296 
 297         # Si les listes ne sont pas completes pour toutes les colonnes transmet les parametres aux premieres colonnes.
 298         # Pour le reste, passe les valeurs par defaut, wx.LIST_FORMAT_LEFT pour aligner et -1 pour la largeur.
 299         columns = self.dataSource.GetColumnHeaders()
 300         for col, text in enumerate(columns):
 301             try: Width = width[col]
 302             except IndexError: Width = -1
 303 
 304             try: Align = align[col]
 305             except IndexError: Align = wx.LIST_FORMAT_LEFT
 306 
 307             self.InsertColumn(col, text, Align, Width)
 308 
 309         #--- mixin
 310         data = dict(enumerate(self.dataSource.row))
 311         print("Data dict :", data)
 312         self.itemDataMap = data
 313         print("Item data map :", self.itemDataMap)
 314         self.itemIndexMap = data.keys()
 315         print("Item index map :", self.itemIndexMap)
 316 
 317         #------------
 318 
 319         self.SetItemCount(len(data))
 320 
 321         #------------
 322 
 323         # Initialize the column sorter.
 324         listmix.ColumnSorterMixin.__init__(self, self.dataSource.GetColCount())
 325 
 326         #------------
 327 
 328         self.Bind(wx.EVT_LIST_COL_CLICK, self.SortItems)
 329 
 330     #-----------------------------------------------------------------------
 331 
 332     #--- Metodi richiamati per la virtualita' della lista.
 333     #--- Methodes appelees pour la liste virtuelle.
 334     def OnGetItemText(self, item, col):
 335         """
 336         ...
 337         """
 338 
 339         # index=self.itemIndexMap[item]
 340         # return self.itemDataMap[index][col]
 341 
 342         data = self.dataSource.GetItem(item)
 343         return str(data[col])
 344 
 345 
 346     def OnGetItemAttr(self, item):
 347         """
 348         ...
 349         """
 350 
 351         return self.itemAttr[item % len(self.itemAttr)]
 352 
 353 
 354     #--- Metodi richiamati per mixin.
 355     #--- Methodes appelees pour mixin.
 356     def GetListCtrl(self):
 357         """
 358         ...
 359         """
 360 
 361         return self
 362 
 363 
 364     def SortItems(self, event):
 365         """
 366         ...
 367         """
 368 
 369         data = self.dataSource.row
 370 
 371         #------------
 372 
 373         col = event.GetColumn()
 374 
 375         #------------
 376 
 377         if col != self.prevColumn:
 378             self.sortAcend = True
 379         else:
 380             if self.sortAcend:
 381                 self.sortAcend = None
 382             else:
 383                 self.sortAcend = True
 384         if self.sortAcend:
 385             data.sort(key=lambda x: x[col])
 386         else:
 387             data.reverse()
 388 
 389         self.prevColumn = col
 390 
 391         #------------
 392 
 393         self.DeleteAllItems()
 394 
 395         #------------
 396 
 397         self.SetItemCount(len(data))
 398 
 399     # def SortItems(self, sorter=cmp):
 400         # items = list(self.itemDataMap.keys())
 401         # items.sort(sorter)
 402         # self.itemIndexMap = items
 403         # ridisegna la lista.
 404         # Redessine la liste.
 405         # self.Refresh()
 406 
 407 #---------------------------------------------------------------------------
 408 
 409 class MyFrame(wx.Frame):
 410     def __init__(self):
 411         wx.Frame.__init__(self, None, -1,
 412                           "Sample eight (properties)",
 413                           size=(500, 506))
 414 
 415         #------------
 416 
 417         self.SetIcon(wx.Icon('icons/wxwin.ico'))
 418         self.SetMinSize((500, 506))
 419 
 420         #------------
 421 
 422         panel = wx.Panel(self, -1)
 423 
 424         #------------
 425 
 426         # Firstname, Sex, Age
 427         col = ["Nome", "Sesso", "Eta"]
 428 
 429         #------------
 430 
 431         row = [
 432                ["Antonio", "M", 36],
 433                ["Letizia", "F", 39],
 434                ["Antonio", "M", 35],
 435                ["Letizia", "F", 39],
 436                ["Roberta", "F", 7],
 437                ["Francesca", "F", 61],
 438               ]*10   # Nombre de rangees.
 439 
 440         #------------
 441 
 442         data = MyDataSource(col, row)
 443 
 444         #------------
 445 
 446         property = {"align":[wx.LIST_FORMAT_LEFT, wx.LIST_FORMAT_CENTRE, wx.LIST_FORMAT_RIGHT],
 447                     "width":[150]*3,
 448                     "itemAttr": [
 449                                  [(10, wx.FONTFAMILY_ROMAN, wx.NORMAL, wx.NORMAL), "white", "black"],
 450                                  [(10, wx.FONTFAMILY_ROMAN, wx.NORMAL, wx.BOLD), (90, 100, 50), (150, 150, 150)],
 451                                  # MyDefaultItemAttr().default_itemAttr
 452                                 ]
 453                     }
 454 
 455         #------------
 456 
 457         data_property = MyProperty(property)
 458 
 459         self.list1 = MyListCtrl(panel, dataSource=data)
 460         self.list2 = MyListCtrl(panel, dataSource=data, property=data_property)
 461         self.list1.Refresh()
 462         self.list2.Refresh()
 463         #------------
 464 
 465         box_sizer = wx.BoxSizer(wx.VERTICAL)
 466 
 467         # MyListCtrl sans proprietes.
 468         box_sizer.Add(wx.StaticText(panel, -1, "MyListCtrl senza 'property'"))
 469         box_sizer.Add(self.list1, 1, wx.EXPAND|wx.BOTTOM, 15)
 470         # MyListCtrl avec proprietes.
 471         box_sizer.Add(wx.StaticText(panel, -1, "MyListCtrl con 'property'"))
 472         box_sizer.Add(self.list2, 1, wx.EXPAND)
 473 
 474         panel.SetSizer(box_sizer)
 475 
 476 #---------------------------------------------------------------------------
 477 
 478 class MyApp(wx.App):
 479     def OnInit(self):
 480 
 481         #------------
 482 
 483         frame = MyFrame()
 484         self.SetTopWindow(frame)
 485         frame.Show(True)
 486 
 487         return True
 488 
 489 #---------------------------------------------------------------------------
 490 
 491 def main():
 492     app = MyApp(False)
 493     app.MainLoop()
 494 
 495 #---------------------------------------------------------------------------
 496 
 497 if __name__ == "__main__" :
 498     main()


Sample nine

img_sample_nine.png

   1 # sample_nine.py
   2 
   3 """
   4 
   5 Author(s)  : ???
   6              Modified and updated for wxPython Phoenix by Ecco
   7 Version    : 0.0.2
   8 Website    : Python-it.org
   9 
  10 """
  11 
  12 import os
  13 import sys
  14 import wx
  15 import wx.lib.mixins.listctrl as listmix
  16 
  17 # class MyDataSource
  18 # class MyDefaultItemAttr
  19 # class MyProperty
  20 # class MyListCtrl
  21 # class MyFrame
  22 # class MyApp
  23 
  24 #---------------------------------------------------------------------------
  25 
  26 class MyDataSource(object):
  27     """
  28     Questa classe acquisiscie i dati da visualizzare nel wx.ListCtrl Virtuale.
  29     Per il suo corretto funzionamento i dati devono provenire da :
  30         - una lista per le intestazioni delle colonne;
  31         - una lista di liste, per le righe.
  32     I parametri passati all'__init__ sono :
  33         col per le intestazioni delle colonne;
  34         row per le righe.
  35 
  36     #------------
  37 
  38     Cette classe acquiere les donnees a afficher dans la wx.ListCtrl virtuelle.
  39     Pour un fonctionnement correct, les donnees doivent provenir de :
  40         - Une liste pour les en-tetes de colonnes;
  41         - Une liste des listes, pour les lignes.
  42     Les parametres passes a __init__ sont :
  43         col pour les en-tetes de colonnes;
  44         row pour les lignes.
  45     """
  46 
  47     def __init__(self, col, row):
  48         """
  49         ...
  50         """
  51 
  52         self.col = col
  53         self.row = row
  54 
  55     #-----------------------------------------------------------------------
  56 
  57     def GetColumnHeaders(self):
  58         """
  59         Ritorna la lista delle Colonne.
  60         Retourne la liste des colonnes.
  61         """
  62 
  63         return self.col
  64 
  65 
  66     def GetCount(self):
  67         """
  68         Ritorna il numero delle Righe.
  69         Retourne le nombre de rangees.
  70         """
  71 
  72         return len(self.row)
  73 
  74 
  75     def GetColCount(self):
  76         """
  77         Ritorna il numero delle Colonne.
  78         Retourne le nombre de colonnes.
  79         """
  80 
  81         return len(self.col)
  82 
  83 
  84     def GetItem(self, index):
  85         """
  86         Ritorna il valore della cella passato ad index.
  87         Retourne la valeur de la cellule transmise a l'index.
  88         """
  89 
  90         return self.row[index]
  91 
  92 
  93     def UpdateCache(self, start, end):
  94         pass
  95 
  96 #---------------------------------------------------------------------------
  97 
  98 class MyDefaultItemAttr(object):
  99     """
 100     Questa e' una classe di comodo per l'assegnazione dei valori di default
 101     dei tre attributi Font, BackgroundColour, TextColour.
 102 
 103     #------------
 104 
 105     C'est une  classe de commodite pour l'attribution des valeurs par defaut
 106     de ces trois attributs Font, BackgroundColour, TextColour.
 107     """
 108 
 109     default_font = (8, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL)
 110     default_BackgroundColour = "white"
 111     default_TextColour = "black"
 112 
 113     default_itemAttr = [default_font, default_BackgroundColour, default_TextColour]
 114 
 115 #---------------------------------------------------------------------------
 116 
 117 class MyProperty(object):
 118     """
 119     Questa classe fornisce le varie proprieta' al wx.ListCtrl Virtuale :
 120         width e' una lista di valori per la larghezza delle colonne, valore di Default ==> [-1];
 121         align e' una lista di valori per l'allinemento delle colonne, valore di Default ==> [wx.LIST_FORMAT_LEFT];
 122         itemAttr e' una lista di valori per gli Attributi di Riga,
 123             permette la creazione di tanti wx.ItemAttr per ogni elemente presente nella lista,
 124             ogni singolo elemento e' composto a sua volta da tre valori, rispettivamente per il Font, per il BackgroundColour e il TextColour
 125             valore di Default ==> [(8, wx.FONTFAMILY_DEFAULT  , wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL), "white", "black"]
 126 
 127         L'__init__ prende un parametro :
 128             property che e' un dizionario con le proprieta' su elencate i cui indici sono le proprieta' stesse.
 129 
 130     #------------
 131 
 132      Cette classe fournie diverses proprietes a la wx.ListCtrl virtuelle :
 133         width est une liste de valeurs pour la largeur des colonnes, valeur par defaut ==> [-1];
 134         align est une liste de valeurs pour l'alignement des colonnes, valeur par defaut, ==> [wx.LIST_FORMAT_LEFT];
 135         itemAttr et une liste de valeurs pour les attributs de Riga,
 136             permet la creation de nombreux wx.ItemAttr pour chaque element present dans la liste,
 137             chaque element individuel est constitue a son tour par trois valeurs, respectivement pour Font, pour BackgroundColour et TextColour
 138             La valeur par defaut ==> [(8, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL), "white", "black"]
 139 
 140         La methode __ init__ prend un parametre :
 141             la propriete est un dictionnaire avec les proprietes dont les indices ont des proprietes qui leur sont propre.
 142     """
 143 
 144     def __init__(self, property):
 145         """
 146         ...
 147         """
 148 
 149         self.property = property
 150 
 151         self.default_font = MyDefaultItemAttr().default_itemAttr
 152         self.default_BackgroundColour = MyDefaultItemAttr().default_BackgroundColour
 153         self.default_TextColour = MyDefaultItemAttr().default_TextColour
 154         self.default_itemAttr = MyDefaultItemAttr().default_itemAttr
 155 
 156     #-----------------------------------------------------------------------
 157 
 158     def get_property(self):
 159         """
 160         Restituisce il dizionario con le propriea' del wx.ListCtrl Virtuale.
 161         Retourne le dictionnaire avec les proprietes de la wx.ListCtrl virtuelle.
 162         """
 163 
 164         return {
 165                 "width": self._get_width(),
 166                 "align": self._get_align(),
 167                 "itemAttr": self._get_itemAttr()
 168                }
 169 
 170 
 171     def _get_property(self, index, default):
 172         """
 173         Metodo interno di comodo per il vari get_*.
 174         Se index non e' presente nel dizionario fa ritornare il valore di Default.
 175 
 176         Methode interne de commodite pour les differents get_*.
 177         Si l'index n'est pas present dans le dictionnaire il retourne la valeur par defaut.
 178         """
 179 
 180         if not self.property.get(index, False):
 181             return default
 182         else:
 183             return self.property[index]
 184 
 185 
 186     #--- Metodi per assegnare i valori alle proprieta'.
 187     # --- Methodes pour attribuer des valeurs a la propriete.
 188     def _get_width(self):
 189         """
 190         Ritorna il valore di width.
 191         Retourne la valeur de la largeur.
 192         """
 193 
 194         return self._get_property("width", [-1])
 195 
 196 
 197     def _get_align(self):
 198         """
 199         Ritorna il valore di align.
 200         Retourne la valeur de l'alignement.
 201         """
 202 
 203         return self._get_property("align", [wx.LIST_FORMAT_LEFT])
 204 
 205 
 206     def _get_itemAttr(self):
 207         """
 208         Ritorna una lista di wx.ItemAttr per Font, Colore Sfondo e Colore Testo
 209         Se uno o piu' valori non sono presenti assegna quello di default.
 210 
 211         Retourne une liste des wx.ItemAttr pour la Font, le BackgroundColour et le ForegroundColour du texte
 212         Si une ou plusieurs valeurs ne sont pas presentes il attribue la valeur par defaut.
 213         """
 214 
 215         def _assign_value(list1, list2):
 216             attr = wx.ItemAttr()
 217             try: attr.SetFont(wx.Font(*list1[0]))
 218             except IndexError and TypeError: attr.SetFont(wx.Font(*list2[0]))
 219 
 220             try: attr.SetBackgroundColour(list1[1])
 221             except IndexError: attr.SetBackgroundColour(list2[1])
 222 
 223             try: attr.SetTextColour(list1[2])
 224             except IndexError: attr.SetTextColour(list2[2])
 225 
 226             return attr
 227 
 228         list_attr = []
 229         for l in self.property.get("itemAttr", [self.default_itemAttr]):
 230             list_attr.append(_assign_value(l, self.default_itemAttr))
 231 
 232         return list_attr
 233 
 234 #---------------------------------------------------------------------------
 235 
 236 class MyListCtrl(wx.ListCtrl,
 237                  listmix.ListCtrlAutoWidthMixin):
 238     """
 239     Questa classe e' il cuore pulsante di MyListCtrl.
 240     L'__init__ richiede due parametri:
 241         dataSource che e' la lista dei valori da visualizzare nella lista;
 242         property che e' il dizionario delle proprieta' della lista, questo parametro e' facoltativo.
 243 
 244     #------------
 245 
 246     Cette classe et le cœur de MyListCtrl.
 247     La methode __ init__ requiert deux parametres:
 248         dataSource est la liste des valeurs a afficher dans la liste;
 249         property et le dictionnaire de la liste des proprietes, ce parametre est optionnel.
 250     """
 251 
 252     def __init__(self, *args, **kwargs):
 253 
 254         self.dataSource = kwargs.pop("dataSource")
 255 
 256         #--- Se property non viene dichiarato ne viene ritornato uno vuoto.
 257         #--- Si la propriete n'est pas declaree, elle est renvoyee a vide.
 258         try:property = kwargs.pop("property")
 259         except KeyError: property=MyProperty({})
 260 
 261         #---
 262 
 263         wx.ListCtrl.__init__(self,
 264                              style=wx.LC_REPORT |
 265                                    wx.LC_VIRTUAL |
 266                                    wx.LC_SINGLE_SEL |
 267                                    wx.LC_VRULES |
 268                                    wx.LC_HRULES,
 269                              *args, **kwargs)
 270 
 271         #------------
 272 
 273         # Initialize the listCtrl auto width.
 274         listmix.ListCtrlAutoWidthMixin.__init__(self)
 275 
 276         #------------
 277 
 278         # Return bitmaps folder.
 279         self.bitmaps_dir = wx.GetApp().GetBitmapsDir()
 280         # Return icons folder.
 281         self.icons_dir = wx.GetApp().GetIconsDir()
 282 
 283         #------------
 284 
 285         # Load some images into an image list.
 286         self.il = wx.ImageList(16, 16, True)
 287 
 288         # Add image for rows.
 289         self.bmp3 = wx.Bitmap(os.path.join(self.bitmaps_dir,
 290                                                "folder.png"))
 291 
 292         # Add images to list.
 293         self.idx1 = self.il.Add(self.bmp3)
 294 
 295         # Assign the image list to it.
 296         self.SetImageList(self.il, wx.IMAGE_LIST_SMALL)
 297 
 298         #------------
 299 
 300         self.prevColumn = None
 301         self.sortAcend = False
 302 
 303         #------------
 304 
 305         width = property.get_property()["width"]            # Larghezza colonne.       # Largeur de colonne.
 306         align = property.get_property()["align"]            # Allineamento colonne.    # Alignement de colonne.
 307         self.itemAttr = property.get_property()["itemAttr"] # Attributi righe.         # Attributs de lignes.
 308 
 309         #--- Crea le colonne :
 310         #--- Creation de colonnes :
 311         #    Se le liste non sono complete per tutte le colonne passa i parametri alle prime n colonne.
 312         #    per le restanti passa i valori di Default, wx.LIST_FORMAT_LEFT per align e -1 per width.
 313 
 314         # Si les listes ne sont pas completes pour toutes les colonnes transmet les parametres aux premieres colonnes.
 315         # Pour le reste, passe les valeurs par defaut, wx.LIST_FORMAT_LEFT pour aligner et -1 pour la largeur.
 316         columns = self.dataSource.GetColumnHeaders()
 317         for col, text in enumerate(columns):
 318             try: Width = width[col]
 319             except IndexError: Width = -1
 320 
 321             try: Align = align[col]
 322             except IndexError: Align = wx.LIST_FORMAT_LEFT
 323 
 324             self.InsertColumn(col, text, Align, Width)
 325 
 326         #--- mixin
 327         data = dict(enumerate(self.dataSource.row))
 328         print("Data dict :", data)
 329         self.itemDataMap = data
 330         print("Item data map :", self.itemDataMap)
 331         self.itemIndexMap = data.keys()
 332         print("Item index map :", self.itemIndexMap)
 333 
 334         #------------
 335 
 336         self.SetItemCount(len(data))
 337 
 338         #------------
 339 
 340         self.Bind(wx.EVT_LIST_COL_CLICK, self.SortItems)
 341 
 342     #-----------------------------------------------------------------------
 343 
 344     #--- Metodi richiamati per la virtualita' della lista.
 345     #--- Methodes appelees pour la liste virtuelle.
 346     def OnGetItemText(self, item, col):
 347         """
 348         ...
 349         """
 350 
 351         # index=self.itemIndexMap[item]
 352         # return self.itemDataMap[index][col]
 353 
 354         data = self.dataSource.GetItem(item)
 355         return str(data[col])
 356 
 357 
 358     def OnGetItemImage(self, item):
 359         """
 360         Return item image (folder).
 361         """
 362 
 363         return self.idx1
 364 
 365 
 366     def OnGetItemAttr(self, item):
 367         """
 368         ...
 369         """
 370 
 371         return self.itemAttr[item % len(self.itemAttr)]
 372 
 373 
 374     #--- Metodi richiamati per mixin.
 375     #--- Methodes appelees pour mixin.
 376     def GetListCtrl(self):
 377         """
 378         ...
 379         """
 380 
 381         return self
 382 
 383 
 384     def SortItems(self, event):
 385         """
 386         ...
 387         """
 388 
 389         data = self.dataSource.row
 390 
 391         #------------
 392 
 393         col = event.GetColumn()
 394 
 395         #------------
 396 
 397         if col != self.prevColumn:
 398             self.sortAcend = True
 399         else:
 400             if self.sortAcend:
 401                 self.sortAcend = None
 402             else:
 403                 self.sortAcend = True
 404         if self.sortAcend:
 405             data.sort(key=lambda x: x[col])
 406         else:
 407             data.reverse()
 408 
 409         self.prevColumn = col
 410 
 411         #------------
 412 
 413         self.DeleteAllItems()
 414 
 415         #------------
 416 
 417         self.SetItemCount(len(data))
 418 
 419     # def SortItems(self, sorter=cmp):
 420         # items = list(self.itemDataMap.keys())
 421         # items.sort(sorter)
 422         # self.itemIndexMap = items
 423         # ridisegna la lista.
 424         # Redessine la liste.
 425         # self.Refresh()
 426 
 427 #---------------------------------------------------------------------------
 428 
 429 class MyFrame(wx.Frame, listmix.ColumnSorterMixin):
 430     def __init__(self):
 431         wx.Frame.__init__(self, None, -1,
 432                           "Sample nine (properties & row icon)",
 433                           size=(500, 506))
 434 
 435         #------------
 436 
 437         self.SetIcon(wx.Icon('icons/wxwin.ico'))
 438         self.SetMinSize((500, 506))
 439 
 440         #------------
 441 
 442         panel = wx.Panel(self, -1)
 443 
 444         #------------
 445 
 446         # Firstname, Sex, Age
 447         col = ["Nome", "Sesso", "Eta"]
 448 
 449         #------------
 450 
 451         row = [
 452                ["Antonio", "M", 36],
 453                ["Letizia", "F", 39],
 454                ["Antonio", "M", 35],
 455                ["Letizia", "F", 39],
 456                ["Roberta", "F", 7],
 457                ["Francesca", "F", 61],
 458               ]*10   # Nombre de rangees.
 459 
 460         #------------
 461 
 462         data = MyDataSource(col, row)
 463 
 464         #------------
 465 
 466         property = {"align":[wx.LIST_FORMAT_LEFT, wx.LIST_FORMAT_CENTRE, wx.LIST_FORMAT_RIGHT],
 467                     "width":[150]*3,
 468                     "itemAttr": [
 469                                  [(10, wx.FONTFAMILY_ROMAN, wx.NORMAL, wx.NORMAL), "white", "black"],
 470                                  [(10, wx.FONTFAMILY_ROMAN, wx.NORMAL, wx.BOLD), (90, 100, 50), (150, 150, 150)],
 471                                  # MyDefaultItemAttr().default_itemAttr
 472                                 ]
 473                     }
 474 
 475         #------------
 476 
 477         data_property = MyProperty(property)
 478 
 479         self.list1 = MyListCtrl(panel, dataSource=data)
 480         self.list2 = MyListCtrl(panel, dataSource=data, property=data_property)
 481 
 482         #------------
 483 
 484         box_sizer = wx.BoxSizer(wx.VERTICAL)
 485 
 486         # MyListCtrl sans proprietes.
 487         box_sizer.Add(wx.StaticText(panel, -1, "MyListCtrl senza 'property'"))
 488         box_sizer.Add(self.list1, 1, wx.EXPAND|wx.BOTTOM, 15)
 489         # MyListCtrl avec proprietes.
 490         box_sizer.Add(wx.StaticText(panel, -1, "MyListCtrl con 'property'"))
 491         box_sizer.Add(self.list2, 1, wx.EXPAND)
 492 
 493         panel.SetSizer(box_sizer)
 494 
 495 #---------------------------------------------------------------------------
 496 
 497 class MyApp(wx.App):
 498     def OnInit(self):
 499 
 500         #------------
 501 
 502         self.installDir = os.path.split(os.path.abspath(sys.argv[0]))[0]
 503 
 504         #------------
 505 
 506         frame = MyFrame()
 507         self.SetTopWindow(frame)
 508         frame.Show(True)
 509 
 510         return True
 511 
 512     #---------------------------------------------------------------------------
 513 
 514     def GetInstallDir(self):
 515         """
 516         Return the installation directory for my application.
 517         """
 518 
 519         return self.installDir
 520 
 521 
 522     def GetIconsDir(self):
 523         """
 524         Return the icons directory for my application.
 525         """
 526 
 527         icons_dir = os.path.join(self.installDir, "icons")
 528         return icons_dir
 529 
 530 
 531     def GetBitmapsDir(self):
 532         """
 533         Return the bitmaps directory for my application.
 534         """
 535 
 536         bitmaps_dir = os.path.join(self.installDir, "bitmaps")
 537         return bitmaps_dir
 538 
 539 #---------------------------------------------------------------------------
 540 
 541 def main():
 542     app = MyApp(False)
 543     app.MainLoop()
 544 
 545 #---------------------------------------------------------------------------
 546 
 547 if __name__ == "__main__" :
 548     main()


Sample ten

img_sample_ten.png

   1 # sample_ten.py
   2 
   3 """
   4 
   5 Author(s)  : ???
   6              Modified and updated for wxPython Phoenix by Ecco
   7 Version    : 0.0.2
   8 Website    : Python-it.org
   9 
  10 """
  11 
  12 import os
  13 import sys
  14 import wx
  15 import wx.lib.mixins.listctrl as listmix
  16 
  17 # class MyDataSource
  18 # class MyDefaultItemAttr
  19 # class MyProperty
  20 # class MyListCtrl
  21 # class MyFrame
  22 # class MyApp
  23 
  24 #---------------------------------------------------------------------------
  25 
  26 class MyDataSource(object):
  27     """
  28     Questa classe acquisiscie i dati da visualizzare nel wx.ListCtrl Virtuale.
  29     Per il suo corretto funzionamento i dati devono provenire da :
  30         - una lista per le intestazioni delle colonne;
  31         - una lista di liste, per le righe.
  32     I parametri passati all'__init__ sono :
  33         col per le intestazioni delle colonne;
  34         row per le righe.
  35 
  36     #------------
  37 
  38     Cette classe acquiere les donnees a afficher dans la wx.ListCtrl virtuelle.
  39     Pour un fonctionnement correct, les donnees doivent provenir de :
  40         - Une liste pour les en-tetes de colonnes;
  41         - Une liste des listes, pour les lignes.
  42     Les parametres passes a __init__ sont :
  43         col pour les en-tetes de colonnes;
  44         row pour les lignes.
  45     """
  46 
  47     def __init__(self, col, row):
  48         """
  49         ...
  50         """
  51 
  52         self.col = col
  53         self.row = row
  54 
  55     #-----------------------------------------------------------------------
  56 
  57     def GetColumnHeaders(self):
  58         """
  59         Ritorna la lista delle Colonne.
  60         Retourne la liste des colonnes.
  61         """
  62 
  63         return self.col
  64 
  65 
  66     def GetCount(self):
  67         """
  68         Ritorna il numero delle Righe.
  69         Retourne le nombre de rangees.
  70         """
  71 
  72         return len(self.row)
  73 
  74 
  75     def GetColCount(self):
  76         """
  77         Ritorna il numero delle Colonne.
  78         Retourne le nombre de colonnes.
  79         """
  80 
  81         return len(self.col)
  82 
  83 
  84     def GetItem(self, index):
  85         """
  86         Ritorna il valore della cella passato ad index.
  87         Retourne la valeur de la cellule transmise a l'index.
  88         """
  89 
  90         return self.row[index]
  91 
  92 
  93     def UpdateCache(self, start, end):
  94         pass
  95 
  96 #---------------------------------------------------------------------------
  97 
  98 class MyDefaultItemAttr(object):
  99     """
 100     Questa e' una classe di comodo per l'assegnazione dei valori di default
 101     dei tre attributi Font, BackgroundColour, TextColour.
 102 
 103     #------------
 104 
 105     C'est une  classe de commodite pour l'attribution des valeurs par defaut
 106     de ces trois attributs Font, BackgroundColour, TextColour.
 107     """
 108 
 109     default_font = (8, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL)
 110     default_BackgroundColour = "white"
 111     default_TextColour = "black"
 112 
 113     default_itemAttr = [default_font, default_BackgroundColour, default_TextColour]
 114 
 115 #---------------------------------------------------------------------------
 116 
 117 class MyProperty(object):
 118     """
 119     Questa classe fornisce le varie proprieta' al wx.ListCtrl Virtuale :
 120         width e' una lista di valori per la larghezza delle colonne, valore di Default ==> [-1];
 121         align e' una lista di valori per l'allinemento delle colonne, valore di Default ==> [wx.LIST_FORMAT_LEFT];
 122         itemAttr e' una lista di valori per gli Attributi di Riga,
 123             permette la creazione di tanti wx.ItemAttr per ogni elemente presente nella lista,
 124             ogni singolo elemento e' composto a sua volta da tre valori, rispettivamente per il Font, per il BackgroundColour e il TextColour
 125             valore di Default ==> [(8, wx.FONTFAMILY_DEFAULT  , wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL), "white", "black"]
 126 
 127         L'__init__ prende un parametro :
 128             property che e' un dizionario con le proprieta' su elencate i cui indici sono le proprieta' stesse.
 129 
 130     #------------
 131 
 132      Cette classe fournie diverses proprietes a la wx.ListCtrl virtuelle :
 133         width est une liste de valeurs pour la largeur des colonnes, valeur par defaut ==> [-1];
 134         align est une liste de valeurs pour l'alignement des colonnes, valeur par defaut, ==> [wx.LIST_FORMAT_LEFT];
 135         itemAttr et une liste de valeurs pour les attributs de Riga,
 136             permet la creation de nombreux wx.ItemAttr pour chaque element present dans la liste,
 137             chaque element individuel est constitue a son tour par trois valeurs, respectivement pour Font, pour BackgroundColour et TextColour
 138             La valeur par defaut ==> [(8, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL), "white", "black"]
 139 
 140         La methode __ init__ prend un parametre :
 141             la propriete est un dictionnaire avec les proprietes dont les indices ont des proprietes qui leur sont propre.
 142     """
 143 
 144     def __init__(self, property):
 145         """
 146         ...
 147         """
 148 
 149         self.property = property
 150 
 151         self.default_font = MyDefaultItemAttr().default_itemAttr
 152         self.default_BackgroundColour = MyDefaultItemAttr().default_BackgroundColour
 153         self.default_TextColour = MyDefaultItemAttr().default_TextColour
 154         self.default_itemAttr = MyDefaultItemAttr().default_itemAttr
 155 
 156     #-----------------------------------------------------------------------
 157 
 158     def get_property(self):
 159         """
 160         Restituisce il dizionario con le propriea' del wx.ListCtrl Virtuale.
 161         Retourne le dictionnaire avec les proprietes de la wx.ListCtrl virtuelle.
 162         """
 163 
 164         return {
 165                 "width": self._get_width(),
 166                 "align": self._get_align(),
 167                 "itemAttr": self._get_itemAttr()
 168                }
 169 
 170 
 171     def _get_property(self, index, default):
 172         """
 173         Metodo interno di comodo per il vari get_*.
 174         Se index non e' presente nel dizionario fa ritornare il valore di Default.
 175 
 176         Methode interne de commodite pour les differents get_*.
 177         Si l'index n'est pas present dans le dictionnaire il retourne la valeur par defaut.
 178         """
 179 
 180         if not self.property.get(index, False):
 181             return default
 182         else:
 183             return self.property[index]
 184 
 185 
 186     #--- Metodi per assegnare i valori alle proprieta'.
 187     # --- Methodes pour attribuer des valeurs a la propriete.
 188     def _get_width(self):
 189         """
 190         Ritorna il valore di width.
 191         Retourne la valeur de la largeur.
 192         """
 193 
 194         return self._get_property("width", [-1])
 195 
 196 
 197     def _get_align(self):
 198         """
 199         Ritorna il valore di align.
 200         Retourne la valeur de l'alignement.
 201         """
 202 
 203         return self._get_property("align", [wx.LIST_FORMAT_LEFT])
 204 
 205 
 206     def _get_itemAttr(self):
 207         """
 208         Ritorna una lista di wx.ItemAttr per Font, Colore Sfondo e Colore Testo
 209         Se uno o piu' valori non sono presenti assegna quello di default.
 210 
 211         Retourne une liste des wx.ItemAttr pour la Font, le BackgroundColour et le ForegroundColour du texte
 212         Si une ou plusieurs valeurs ne sont pas presentes il attribue la valeur par defaut.
 213         """
 214 
 215         def _assign_value(list1, list2):
 216             attr = wx.ItemAttr()
 217             try: attr.SetFont(wx.Font(*list1[0]))
 218             except IndexError and TypeError: attr.SetFont(wx.Font(*list2[0]))
 219 
 220             try: attr.SetBackgroundColour(list1[1])
 221             except IndexError: attr.SetBackgroundColour(list2[1])
 222 
 223             try: attr.SetTextColour(list1[2])
 224             except IndexError: attr.SetTextColour(list2[2])
 225 
 226             return attr
 227 
 228         list_attr = []
 229         for l in self.property.get("itemAttr", [self.default_itemAttr]):
 230             list_attr.append(_assign_value(l, self.default_itemAttr))
 231 
 232         return list_attr
 233 
 234 #---------------------------------------------------------------------------
 235 
 236 class MyListCtrl(wx.ListCtrl,
 237                  listmix.ListCtrlAutoWidthMixin):
 238     """
 239     Questa classe e' il cuore pulsante di MyListCtrl.
 240     L'__init__ richiede due parametri:
 241         dataSource che e' la lista dei valori da visualizzare nella lista;
 242         property che e' il dizionario delle proprieta' della lista, questo parametro e' facoltativo.
 243 
 244     #------------
 245 
 246     Cette classe et le cœur de MyListCtrl.
 247     La methode __ init__ requiert deux parametres:
 248         dataSource est la liste des valeurs a afficher dans la liste;
 249         property et le dictionnaire de la liste des proprietes, ce parametre est optionnel.
 250     """
 251 
 252     def __init__(self, *args, **kwargs):
 253 
 254         self.dataSource = kwargs.pop("dataSource")
 255 
 256         #--- Se property non viene dichiarato ne viene ritornato uno vuoto.
 257         #--- Si la propriete n'est pas declaree, elle est renvoyee a vide.
 258         try:property = kwargs.pop("property")
 259         except KeyError: property=MyProperty({})
 260 
 261         #---
 262 
 263         wx.ListCtrl.__init__(self,
 264                              style=wx.LC_REPORT |
 265                                    wx.LC_VIRTUAL |
 266                                    wx.LC_SINGLE_SEL |
 267                                    wx.LC_VRULES |
 268                                    wx.LC_HRULES,
 269                              *args, **kwargs)
 270 
 271         #------------
 272 
 273         # Initialize the listCtrl auto width.
 274         listmix.ListCtrlAutoWidthMixin.__init__(self)
 275 
 276         #------------
 277 
 278         # Return bitmaps folder.
 279         self.bitmaps_dir = wx.GetApp().GetBitmapsDir()
 280         # Return icons folder.
 281         self.icons_dir = wx.GetApp().GetIconsDir()
 282 
 283         #------------
 284 
 285         # Load some images into an image list.
 286         self.il = wx.ImageList(16, 16, True)
 287 
 288         # Add arrows for the column sorter.
 289         self.bmp1 = wx.Bitmap(os.path.join(self.bitmaps_dir,
 290                                            "sm_up.png"))
 291         self.bmp2 = wx.Bitmap(os.path.join(self.bitmaps_dir,
 292                                            "sm_down.png"))
 293 
 294         # Add image for rows.
 295         self.bmp3 = wx.Bitmap(os.path.join(self.bitmaps_dir,
 296                                                "folder.png"))
 297 
 298         # Add images to list.
 299         self.sm_up = self.il.Add(self.bmp1)
 300         self.sm_dn = self.il.Add(self.bmp2)
 301         self.idx1 = self.il.Add(self.bmp3)
 302 
 303         empty = self.makeBlank()
 304         self.idx2 = self.il.Add(empty)
 305 
 306         # Assign the image list to it.
 307         self.SetImageList(self.il, wx.IMAGE_LIST_SMALL)
 308 
 309         #------------
 310 
 311         self.prevColumn = None
 312         self.sortAcend = False
 313 
 314         #------------
 315 
 316         width = property.get_property()["width"]            # Larghezza colonne.       # Largeur de colonne.
 317         align = property.get_property()["align"]            # Allineamento colonne.    # Alignement de colonne.
 318         self.itemAttr = property.get_property()["itemAttr"] # Attributi righe.         # Attributs de lignes.
 319 
 320         #--- Crea le colonne :
 321         #--- Creation de colonnes :
 322         #    Se le liste non sono complete per tutte le colonne passa i parametri alle prime n colonne.
 323         #    per le restanti passa i valori di Default, wx.LIST_FORMAT_LEFT per align e -1 per width.
 324 
 325         # Si les listes ne sont pas completes pour toutes les colonnes transmet les parametres aux premieres colonnes.
 326         # Pour le reste, passe les valeurs par defaut, wx.LIST_FORMAT_LEFT pour aligner et -1 pour la largeur.
 327         columns = self.dataSource.GetColumnHeaders()
 328         for col, text in enumerate(columns):
 329             try: Width = width[col]
 330             except IndexError: Width = -1
 331 
 332             try: Align = align[col]
 333             except IndexError: Align = wx.LIST_FORMAT_LEFT
 334 
 335             self.InsertColumn(col, text, Align, Width)
 336 
 337         #---- mixin
 338         data = dict(enumerate(self.dataSource.row))
 339         print("Data dict :", data)
 340         self.itemDataMap = data
 341         print("Item data map :", self.itemDataMap)
 342         self.itemIndexMap = data.keys()
 343         print("Item index map :", self.itemIndexMap)
 344 
 345         #------------
 346 
 347         self.SetItemCount(len(data))
 348 
 349         #------------
 350 
 351         self.Bind(wx.EVT_LIST_COL_CLICK, self.SortItems)
 352 
 353     #-----------------------------------------------------------------------
 354 
 355     def makeBlank(self):
 356         """
 357         ...
 358         """
 359 
 360         empty = wx.Bitmap(16, 16, 32)
 361         dc = wx.MemoryDC(empty)
 362         dc.SetBackground(wx.Brush((0, 0 ,0, 0)))
 363         dc.Clear()
 364         del dc
 365         empty.SetMaskColour((0, 0, 0))
 366         return empty
 367 
 368 
 369     #--- Metodi richiamati per la virtualita' della lista.
 370     #--- Methodes appelees pour la liste virtuelle.
 371     def OnGetItemText(self, item, col):
 372         """
 373         ...
 374         """
 375 
 376         # index=self.itemIndexMap[item]
 377         # return self.itemDataMap[index][col]
 378 
 379         data = self.dataSource.GetItem(item)
 380         return str(data[col])
 381 
 382 
 383     def OnGetItemImage(self, item):
 384         """
 385         Return item image (folder).
 386         """
 387 
 388         return self.idx1
 389 
 390 
 391     def OnGetItemAttr(self, item):
 392         """
 393         ...
 394         """
 395 
 396         return self.itemAttr[item % len(self.itemAttr)]
 397 
 398 
 399     #--- Metodi richiamati per mixin.
 400     #--- Methodes appelees pour mixin.
 401     def GetListCtrl(self):
 402         """
 403         ...
 404         """
 405 
 406         return self
 407 
 408 
 409     # Used by the ColumnSorterMixin,
 410     # see wx/lib/mixins/listctrl.py
 411     def GetSortImages(self):        # Not used.
 412         """
 413         Return sort images.
 414         """
 415 
 416         return (self.sm_dn, self.sm_up)
 417 
 418 
 419     def SortItems(self, event):
 420         """
 421         This sample works fine for the header
 422         icon but is not recommanded.
 423         """
 424 
 425         data = self.dataSource.row
 426 
 427         #------------
 428 
 429         col = event.GetColumn()
 430 
 431         #------------
 432 
 433         if col != self.prevColumn:
 434             self.sortAcend = True
 435         else:
 436             if self.sortAcend:
 437                 self.sortAcend = None
 438             else:
 439                 self.sortAcend = True
 440         if self.sortAcend:
 441             data.sort(key=lambda x: x[col])
 442             if col == 0:
 443                 self.SetColumnImage(0, self.sm_up)
 444                 self.SetColumnImage(1, self.idx2)
 445                 self.SetColumnImage(2, self.idx2)
 446 
 447             elif col == 1:
 448                 self.SetColumnImage(0, self.idx2)
 449                 self.SetColumnImage(1, self.sm_up)
 450                 self.SetColumnImage(2, self.idx2)
 451 
 452             elif col == 2:
 453                 self.SetColumnImage(0, self.idx2)
 454                 self.SetColumnImage(1, self.idx2)
 455                 self.SetColumnImage(2, self.sm_up)
 456         else:
 457             data.reverse()
 458 
 459             if col == 0:
 460                 self.SetColumnImage(0, self.sm_dn)
 461                 self.SetColumnImage(1, self.idx2)
 462                 self.SetColumnImage(2, self.idx2)
 463 
 464             elif col == 1:
 465                 self.SetColumnImage(0, self.idx2)
 466                 self.SetColumnImage(1, self.sm_dn)
 467                 self.SetColumnImage(2, self.idx2)
 468 
 469             elif col == 2:
 470                 self.SetColumnImage(0, self.idx2)
 471                 self.SetColumnImage(1, self.idx2)
 472                 self.SetColumnImage(2, self.sm_dn)
 473 
 474         self.prevColumn = col
 475 
 476         #------------
 477 
 478         self.DeleteAllItems()
 479 
 480         #------------
 481 
 482         self.SetItemCount(len(data))
 483 
 484 
 485     # def SortItems(self, sorter=cmp):
 486         # items = list(self.itemDataMap.keys())
 487         # items.sort(sorter)
 488         # self.itemIndexMap = items
 489         # ridisegna la lista.
 490         # Redessine la liste.
 491         # self.Refresh()
 492 
 493 #---------------------------------------------------------------------------
 494 
 495 class MyFrame(wx.Frame, listmix.ColumnSorterMixin):
 496     def __init__(self):
 497         wx.Frame.__init__(self, None, -1,
 498                           "Sample ten (properties & row/header icon)",
 499                           size=(500, 506))
 500 
 501         #------------
 502 
 503         self.SetIcon(wx.Icon('icons/wxwin.ico'))
 504         self.SetMinSize((500, 506))
 505 
 506         #------------
 507 
 508         panel = wx.Panel(self, -1)
 509 
 510         #------------
 511 
 512         # Firstname, Sex, Age
 513         col = ["Nome", "Sesso", "Eta"]
 514 
 515         #------------
 516 
 517         row = [
 518                ["Antonio", "M", 36],
 519                ["Letizia", "F", 39],
 520                ["Antonio", "M", 35],
 521                ["Letizia", "F", 39],
 522                ["Roberta", "F", 7],
 523                ["Francesca", "F", 61],
 524               ]*10   # Nombre de rangees.
 525 
 526         #------------
 527 
 528         data = MyDataSource(col, row)
 529 
 530         #------------
 531 
 532         property = {"align":[wx.LIST_FORMAT_LEFT, wx.LIST_FORMAT_CENTRE, wx.LIST_FORMAT_RIGHT],
 533                     "width":[150]*3,
 534                     "itemAttr": [
 535                                  [(10, wx.FONTFAMILY_ROMAN, wx.NORMAL, wx.NORMAL), "white", "black"],
 536                                  [(10, wx.FONTFAMILY_ROMAN, wx.NORMAL, wx.BOLD), (90, 100, 50), (150, 150, 150)],
 537                                  # MyDefaultItemAttr().default_itemAttr
 538                                 ]
 539                     }
 540 
 541         #------------
 542 
 543         data_property = MyProperty(property)
 544 
 545         self.list1 = MyListCtrl(panel, dataSource=data)
 546         self.list2 = MyListCtrl(panel, dataSource=data, property=data_property)
 547 
 548         #------------
 549 
 550         box_sizer = wx.BoxSizer(wx.VERTICAL)
 551 
 552         # MyListCtrl sans proprietes.
 553         box_sizer.Add(wx.StaticText(panel, -1, "MyListCtrl senza 'property'"))
 554         box_sizer.Add(self.list1, 1, wx.EXPAND|wx.BOTTOM, 15)
 555         # MyListCtrl avec proprietes.
 556         box_sizer.Add(wx.StaticText(panel, -1, "MyListCtrl con 'property'"))
 557         box_sizer.Add(self.list2, 1, wx.EXPAND)
 558 
 559         panel.SetSizer(box_sizer)
 560 
 561 #---------------------------------------------------------------------------
 562 
 563 class MyApp(wx.App):
 564     def OnInit(self):
 565 
 566         #------------
 567 
 568         self.installDir = os.path.split(os.path.abspath(sys.argv[0]))[0]
 569 
 570         #------------
 571 
 572         frame = MyFrame()
 573         self.SetTopWindow(frame)
 574         frame.Show(True)
 575 
 576         return True
 577 
 578     #---------------------------------------------------------------------------
 579 
 580     def GetInstallDir(self):
 581         """
 582         Return the installation directory for my application.
 583         """
 584 
 585         return self.installDir
 586 
 587 
 588     def GetIconsDir(self):
 589         """
 590         Return the icons directory for my application.
 591         """
 592 
 593         icons_dir = os.path.join(self.installDir, "icons")
 594         return icons_dir
 595 
 596 
 597     def GetBitmapsDir(self):
 598         """
 599         Return the bitmaps directory for my application.
 600         """
 601 
 602         bitmaps_dir = os.path.join(self.installDir, "bitmaps")
 603         return bitmaps_dir
 604 
 605 #---------------------------------------------------------------------------
 606 
 607 def main():
 608     app = MyApp(False)
 609     app.MainLoop()
 610 
 611 #---------------------------------------------------------------------------
 612 
 613 if __name__ == "__main__" :
 614     main()

Sample eleven

img_sample_eleven.png

   1 # sample_eleven.py
   2 
   3 """
   4 
   5 Author(s)  : ???
   6              Modified and updated for wxPython Phoenix by Ecco
   7 Version    : 0.0.2
   8 Website    : Python-it.org
   9 
  10 """
  11 
  12 import os
  13 import sys
  14 import wx
  15 import wx.lib.mixins.listctrl as listmix
  16 
  17 # class MyDataSource
  18 # class MyDefaultItemAttr
  19 # class MyProperty
  20 # class MyListCtrl
  21 # class MyFrame
  22 # class MyApp
  23 
  24 #---------------------------------------------------------------------------
  25 
  26 class MyDataSource(object):
  27     """
  28     Questa classe acquisiscie i dati da visualizzare nel wx.ListCtrl Virtuale.
  29     Per il suo corretto funzionamento i dati devono provenire da :
  30         - una lista per le intestazioni delle colonne;
  31         - una lista di liste, per le righe.
  32     I parametri passati all'__init__ sono :
  33         col per le intestazioni delle colonne;
  34         row per le righe.
  35 
  36     #------------
  37 
  38     Cette classe acquiere les donnees a afficher dans la wx.ListCtrl virtuelle.
  39     Pour un fonctionnement correct, les donnees doivent provenir de :
  40         - Une liste pour les en-tetes de colonnes;
  41         - Une liste des listes, pour les lignes.
  42     Les parametres passes a __init__ sont :
  43         col pour les en-tetes de colonnes;
  44         row pour les lignes.
  45     """
  46 
  47     def __init__(self, col, row):
  48         """
  49         ...
  50         """
  51 
  52         self.col = col
  53         self.row = row
  54 
  55     #-----------------------------------------------------------------------
  56 
  57     def GetColumnHeaders(self):
  58         """
  59         Ritorna la lista delle Colonne.
  60         Retourne la liste des colonnes.
  61         """
  62 
  63         return self.col
  64 
  65 
  66     def GetCount(self):
  67         """
  68         Ritorna il numero delle Righe.
  69         Retourne le nombre de rangees.
  70         """
  71 
  72         return len(self.row)
  73 
  74 
  75     def GetColCount(self):
  76         """
  77         Ritorna il numero delle Colonne.
  78         Retourne le nombre de colonnes.
  79         """
  80 
  81         return len(self.col)
  82 
  83 
  84     def GetItem(self, index):
  85         """
  86         Ritorna il valore della cella passato ad index.
  87         Retourne la valeur de la cellule transmise a l'index.
  88         """
  89 
  90         return self.row[index]
  91 
  92 
  93     def UpdateCache(self, start, end):
  94         pass
  95 
  96 #---------------------------------------------------------------------------
  97 
  98 class MyDefaultItemAttr(object):
  99     """
 100     Questa e' una classe di comodo per l'assegnazione dei valori di default
 101     dei tre attributi Font, BackgroundColour, TextColour.
 102 
 103     #------------
 104 
 105     C'est une  classe de commodite pour l'attribution des valeurs par defaut
 106     de ces trois attributs Font, BackgroundColour, TextColour.
 107     """
 108 
 109     default_font = (8, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL)
 110     default_BackgroundColour = "white"
 111     default_TextColour = "black"
 112 
 113     default_itemAttr = [default_font, default_BackgroundColour, default_TextColour]
 114 
 115 #---------------------------------------------------------------------------
 116 
 117 class MyProperty(object):
 118     """
 119     Questa classe fornisce le varie proprieta' al wx.ListCtrl Virtuale :
 120         width e' una lista di valori per la larghezza delle colonne, valore di Default ==> [-1];
 121         align e' una lista di valori per l'allinemento delle colonne, valore di Default ==> [wx.LIST_FORMAT_LEFT];
 122         itemAttr e' una lista di valori per gli Attributi di Riga,
 123             permette la creazione di tanti wx.ItemAttr per ogni elemente presente nella lista,
 124             ogni singolo elemento e' composto a sua volta da tre valori, rispettivamente per il Font, per il BackgroundColour e il TextColour
 125             valore di Default ==> [(8, wx.FONTFAMILY_DEFAULT  , wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL), "white", "black"]
 126 
 127         L'__init__ prende un parametro :
 128             property che e' un dizionario con le proprieta' su elencate i cui indici sono le proprieta' stesse.
 129 
 130     #------------
 131 
 132      Cette classe fournie diverses proprietes a la wx.ListCtrl virtuelle :
 133         width est une liste de valeurs pour la largeur des colonnes, valeur par defaut ==> [-1];
 134         align est une liste de valeurs pour l'alignement des colonnes, valeur par defaut, ==> [wx.LIST_FORMAT_LEFT];
 135         itemAttr et une liste de valeurs pour les attributs de Riga,
 136             permet la creation de nombreux wx.ItemAttr pour chaque element present dans la liste,
 137             chaque element individuel est constitue a son tour par trois valeurs, respectivement pour Font, pour BackgroundColour et TextColour
 138             La valeur par defaut ==> [(8, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL), "white", "black"]
 139 
 140         La methode __ init__ prend un parametre :
 141             la propriete est un dictionnaire avec les proprietes dont les indices ont des proprietes qui leur sont propre.
 142     """
 143 
 144     def __init__(self, property):
 145         """
 146         ...
 147         """
 148 
 149         self.property = property
 150 
 151         self.default_font = MyDefaultItemAttr().default_itemAttr
 152         self.default_BackgroundColour = MyDefaultItemAttr().default_BackgroundColour
 153         self.default_TextColour = MyDefaultItemAttr().default_TextColour
 154         self.default_itemAttr = MyDefaultItemAttr().default_itemAttr
 155 
 156     #-----------------------------------------------------------------------
 157 
 158     def get_property(self):
 159         """
 160         Restituisce il dizionario con le propriea' del wx.ListCtrl Virtuale.
 161         Retourne le dictionnaire avec les proprietes de la wx.ListCtrl virtuelle.
 162         """
 163 
 164         return {
 165                 "width": self._get_width(),
 166                 "align": self._get_align(),
 167                 "itemAttr": self._get_itemAttr()
 168                }
 169 
 170 
 171     def _get_property(self, index, default):
 172         """
 173         Metodo interno di comodo per il vari get_*.
 174         Se index non e' presente nel dizionario fa ritornare il valore di Default.
 175 
 176         Methode interne de commodite pour les differents get_*.
 177         Si l'index n'est pas present dans le dictionnaire il retourne la valeur par defaut.
 178         """
 179 
 180         if not self.property.get(index, False):
 181             return default
 182         else:
 183             return self.property[index]
 184 
 185 
 186     #--- Metodi per assegnare i valori alle proprieta'.
 187     # --- Methodes pour attribuer des valeurs a la propriete.
 188     def _get_width(self):
 189         """
 190         Ritorna il valore di width.
 191         Retourne la valeur de la largeur.
 192         """
 193 
 194         return self._get_property("width", [-1])
 195 
 196 
 197     def _get_align(self):
 198         """
 199         Ritorna il valore di align.
 200         Retourne la valeur de l'alignement.
 201         """
 202 
 203         return self._get_property("align", [wx.LIST_FORMAT_LEFT])
 204 
 205 
 206     def _get_itemAttr(self):
 207         """
 208         Ritorna una lista di wx.ItemAttr per Font, Colore Sfondo e Colore Testo
 209         Se uno o piu' valori non sono presenti assegna quello di default.
 210 
 211         Retourne une liste des wx.ItemAttr pour la Font, le BackgroundColour et le ForegroundColour du texte
 212         Si une ou plusieurs valeurs ne sont pas presentes il attribue la valeur par defaut.
 213         """
 214 
 215         def _assign_value(list1, list2):
 216             attr = wx.ItemAttr()
 217             try: attr.SetFont(wx.Font(*list1[0]))
 218             except IndexError and TypeError: attr.SetFont(wx.Font(*list2[0]))
 219 
 220             try: attr.SetBackgroundColour(list1[1])
 221             except IndexError: attr.SetBackgroundColour(list2[1])
 222 
 223             try: attr.SetTextColour(list1[2])
 224             except IndexError: attr.SetTextColour(list2[2])
 225 
 226             return attr
 227 
 228         list_attr = []
 229         for l in self.property.get("itemAttr", [self.default_itemAttr]):
 230             list_attr.append(_assign_value(l, self.default_itemAttr))
 231 
 232         return list_attr
 233 
 234 #---------------------------------------------------------------------------
 235 
 236 class MyListCtrl(wx.ListCtrl,
 237                  listmix.ColumnSorterMixin,
 238                  listmix.ListCtrlAutoWidthMixin):
 239     """
 240     Questa classe e' il cuore pulsante di MyListCtrl.
 241     L'__init__ richiede due parametri:
 242         dataSource che e' la lista dei valori da visualizzare nella lista;
 243         property che e' il dizionario delle proprieta' della lista, questo parametro e' facoltativo.
 244 
 245     #------------
 246 
 247     Cette classe et le cœur de MyListCtrl.
 248     La methode __ init__ requiert deux parametres:
 249         dataSource est la liste des valeurs a afficher dans la liste;
 250         property et le dictionnaire de la liste des proprietes, ce parametre est optionnel.
 251     """
 252 
 253     def __init__(self, *args, **kwargs):
 254 
 255         self.dataSource = kwargs.pop("dataSource")
 256 
 257         #--- Se property non viene dichiarato ne viene ritornato uno vuoto.
 258         #--- Si la propriete n'est pas declaree, elle est renvoyee a vide.
 259         try:property = kwargs.pop("property")
 260         except KeyError: property=MyProperty({})
 261 
 262         #---
 263 
 264         wx.ListCtrl.__init__(self,
 265                              style=wx.LC_REPORT |
 266                                    wx.LC_VIRTUAL |
 267                                    wx.LC_SINGLE_SEL |
 268                                    wx.LC_VRULES |
 269                                    wx.LC_HRULES,
 270                              *args, **kwargs)
 271 
 272         #------------
 273 
 274         # Initialize the listCtrl auto width.
 275         listmix.ListCtrlAutoWidthMixin.__init__(self)
 276 
 277         #------------
 278 
 279         # Return bitmaps folder.
 280         self.bitmaps_dir = wx.GetApp().GetBitmapsDir()
 281         # Return icons folder.
 282         self.icons_dir = wx.GetApp().GetIconsDir()
 283 
 284         #------------
 285 
 286         # Load some images into an image list.
 287         self.il = wx.ImageList(16, 16, True)
 288 
 289         # Add arrows for the column sorter.
 290         self.bmp1 = wx.Bitmap(os.path.join(self.bitmaps_dir,
 291                                            "sm_up.png"))
 292         self.bmp2 = wx.Bitmap(os.path.join(self.bitmaps_dir,
 293                                            "sm_down.png"))
 294 
 295         # Add image for rows.
 296         self.bmp3 = wx.Bitmap(os.path.join(self.bitmaps_dir,
 297                                                "folder.png"))
 298 
 299         # Add images to list.
 300         self.sm_up = self.il.Add(self.bmp1)
 301         self.sm_dn = self.il.Add(self.bmp2)
 302         self.idx1 = self.il.Add(self.bmp3)
 303 
 304         empty = self.makeBlank()
 305         self.idx2 = self.il.Add(empty)
 306 
 307         # Assign the image list to it.
 308         self.SetImageList(self.il, wx.IMAGE_LIST_SMALL)
 309 
 310         #------------
 311 
 312         self.oldsortcolumn = -1
 313         self.sort_asc = False
 314 
 315         #------------
 316 
 317         width = property.get_property()["width"]            # Larghezza colonne.       # Largeur de colonne.
 318         align = property.get_property()["align"]            # Allineamento colonne.    # Alignement de colonne.
 319         self.itemAttr = property.get_property()["itemAttr"] # Attributi righe.         # Attributs de lignes.
 320 
 321         #--- Crea le colonne :
 322         #--- Creation de colonnes :
 323         #    Se le liste non sono complete per tutte le colonne passa i parametri alle prime n colonne.
 324         #    per le restanti passa i valori di Default, wx.LIST_FORMAT_LEFT per align e -1 per width.
 325 
 326         # Si les listes ne sont pas completes pour toutes les colonnes transmet les parametres aux premieres colonnes.
 327         # Pour le reste, passe les valeurs par defaut, wx.LIST_FORMAT_LEFT pour aligner et -1 pour la largeur.
 328         columns = self.dataSource.GetColumnHeaders()
 329         for col, text in enumerate(columns):
 330             try: Width = width[col]
 331             except IndexError: Width = -1
 332 
 333             try: Align = align[col]
 334             except IndexError: Align = wx.LIST_FORMAT_LEFT
 335 
 336             self.InsertColumn(col, text, Align, Width)
 337 
 338         #--- mixin
 339         data = dict(enumerate(self.dataSource.row))
 340         print("Data dict :", data)
 341         self.itemDataMap = data
 342         print("Item data map :", self.itemDataMap)
 343         self.itemIndexMap = data.keys()
 344         print("Item index map :", self.itemIndexMap)
 345 
 346         #------------
 347 
 348         # Initialize the column sorter.
 349         listmix.ColumnSorterMixin.__init__(self, self.GetColumnCount())
 350 
 351         #------------
 352 
 353         self.SetItemCount(len(data))
 354         # self.SortListItems(0, True)
 355 
 356     #-----------------------------------------------------------------------
 357 
 358     def makeBlank(self):
 359         """
 360         ...
 361         """
 362 
 363         empty = wx.Bitmap(16, 16, 32)
 364         dc = wx.MemoryDC(empty)
 365         dc.SetBackground(wx.Brush((0, 0 ,0, 0)))
 366         dc.Clear()
 367         del dc
 368         empty.SetMaskColour((0, 0, 0))
 369         return empty
 370 
 371 
 372     #--- Metodi richiamati per la virtualita' della lista.
 373     #--- Methodes appelees pour la liste virtuelle.
 374     def OnGetItemText(self, item, col):
 375         """
 376         ...
 377         """
 378 
 379         # index=self.itemIndexMap[item]
 380         # return self.itemDataMap[index][col]
 381 
 382         data = self.dataSource.GetItem(item)
 383         return str(data[col])
 384 
 385 
 386     def OnGetItemImage(self, item):
 387         """
 388         Return item image (folder).
 389         """
 390 
 391         return self.idx1
 392 
 393 
 394     def OnGetItemAttr(self, item):
 395         """
 396         ...
 397         """
 398 
 399         return self.itemAttr[item % len(self.itemAttr)]
 400 
 401 
 402     #--- Metodi richiamati per mixin.
 403     #--- Methodes appelees pour mixin.
 404     def GetListCtrl(self):
 405         """
 406         ...
 407         """
 408 
 409         return self
 410 
 411 
 412     # Used by the ColumnSorterMixin,
 413     # see wx/lib/mixins/listctrl.py
 414     def GetSortImages(self):        # Not used.
 415         """
 416         Return sort images.
 417         """
 418 
 419         return (self.sm_dn, self.sm_up)
 420 
 421 
 422     def OnSortOrderChanged(self):
 423         """
 424         It's better but is it correct ?
 425         """
 426 
 427         data = self.dataSource.row
 428 
 429         #------------
 430 
 431         if self.oldsortcolumn != -1:
 432             self.sort_asc = True
 433             self.ClearColumnImage(self.oldsortcolumn)
 434         else:
 435             if self.sort_asc:
 436                 self.sort_asc = None
 437             else:
 438                 self.sort_asc = True
 439 
 440         if self.sort_asc:
 441             if self._colSortFlag[self._col]:
 442                 data.sort(key=lambda x: x[self._col])
 443                 idx = self.sm_up
 444             else:
 445                 data.sort(key=lambda x: x[self._col])
 446                 data.reverse()
 447                 idx = self.sm_dn
 448 
 449         #------------
 450 
 451         self.SetColumnImage(self._col, idx)
 452 
 453         #------------
 454 
 455         self.oldsortcolumn = self._col
 456 
 457         #------------
 458 
 459         self.DeleteAllItems()
 460 
 461         #------------
 462 
 463         self.SetItemCount(len(data))
 464 
 465 
 466     # def SortItems(self, sorter=cmp):
 467         # items = list(self.itemDataMap.keys())
 468         # items.sort(sorter)
 469         # self.itemIndexMap = items
 470         # ridisegna la lista.
 471         # Redessine la liste.
 472         # self.Refresh()
 473 
 474 #---------------------------------------------------------------------------
 475 
 476 class MyFrame(wx.Frame):
 477     def __init__(self):
 478         wx.Frame.__init__(self, None, -1,
 479                           "Sample eleven (properties & row/header icon)",
 480                           size=(500, 506))
 481 
 482         #------------
 483 
 484         self.SetIcon(wx.Icon('icons/wxwin.ico'))
 485         self.SetMinSize((500, 506))
 486 
 487         #------------
 488 
 489         panel = wx.Panel(self, -1)
 490 
 491         #------------
 492 
 493         # Firstname, Sex, Age
 494         col = ["Nome", "Sesso", "Eta"]
 495 
 496         #------------
 497 
 498         row = [
 499                ["Antonio", "M", 36],
 500                ["Letizia", "F", 39],
 501                ["Antonio", "M", 35],
 502                ["Letizia", "F", 39],
 503                ["Roberta", "F", 7],
 504                ["Francesca", "F", 61],
 505               ]*10   # Nombre de rangees.
 506 
 507         #------------
 508 
 509         data = MyDataSource(col, row)
 510 
 511         #------------
 512 
 513         property = {"align":[wx.LIST_FORMAT_LEFT, wx.LIST_FORMAT_CENTRE, wx.LIST_FORMAT_RIGHT],
 514                     "width":[150]*3,
 515                     "itemAttr": [
 516                                  [(10, wx.FONTFAMILY_ROMAN, wx.NORMAL, wx.NORMAL), "white", "black"],
 517                                  [(10, wx.FONTFAMILY_ROMAN, wx.NORMAL, wx.BOLD), (90, 100, 50), (150, 150, 150)],
 518                                  # MyDefaultItemAttr().default_itemAttr
 519                                 ]
 520                     }
 521 
 522         #------------
 523 
 524         data_property = MyProperty(property)
 525 
 526         self.list1 = MyListCtrl(panel, dataSource=data)
 527         self.list2 = MyListCtrl(panel, dataSource=data, property=data_property)
 528 
 529         #------------
 530 
 531         box_sizer = wx.BoxSizer(wx.VERTICAL)
 532 
 533         # MyListCtrl sans proprietes.
 534         box_sizer.Add(wx.StaticText(panel, -1, "MyListCtrl senza 'property'"))
 535         box_sizer.Add(self.list1, 1, wx.EXPAND|wx.BOTTOM, 15)
 536         # MyListCtrl avec proprietes.
 537         box_sizer.Add(wx.StaticText(panel, -1, "MyListCtrl con 'property'"))
 538         box_sizer.Add(self.list2, 1, wx.EXPAND)
 539 
 540         panel.SetSizer(box_sizer)
 541 
 542 #---------------------------------------------------------------------------
 543 
 544 class MyApp(wx.App):
 545     def OnInit(self):
 546 
 547         #------------
 548 
 549         self.installDir = os.path.split(os.path.abspath(sys.argv[0]))[0]
 550 
 551         #------------
 552 
 553         frame = MyFrame()
 554         self.SetTopWindow(frame)
 555         frame.Show(True)
 556 
 557         return True
 558 
 559     #-----------------------------------------------------------------------
 560 
 561     def GetInstallDir(self):
 562         """
 563         Return the installation directory for my application.
 564         """
 565 
 566         return self.installDir
 567 
 568 
 569     def GetIconsDir(self):
 570         """
 571         Return the icons directory for my application.
 572         """
 573 
 574         icons_dir = os.path.join(self.installDir, "icons")
 575         return icons_dir
 576 
 577 
 578     def GetBitmapsDir(self):
 579         """
 580         Return the bitmaps directory for my application.
 581         """
 582 
 583         bitmaps_dir = os.path.join(self.installDir, "bitmaps")
 584         return bitmaps_dir
 585 
 586 #---------------------------------------------------------------------------
 587 
 588 def main():
 589     app = MyApp(False)
 590     app.MainLoop()
 591 
 592 #---------------------------------------------------------------------------
 593 
 594 if __name__ == "__main__" :
 595     main()


Download source

source.zip


Additional Information

Link :

http://jak-o-shadows.users.sourceforge.net/python/wxpy/dblistctrl.html

http://wxpython-users.1045709.n5.nabble.com/Example-of-Database-Interaction-td2361801.html

http://www.kitebird.com/articles/pydbapi.html

https://dabodev.com/

https://www.pgadmin.org/download/

https://github.com/1966bc/pyggybank

https://sourceforge.net/projects/pyggybank/

- - - - -

https://wiki.wxpython.org/TitleIndex

https://docs.wxpython.org/


Thanks to

Sakura (sample_three / four / five.py coding), Python-it.org (sample_seven / eight / ten.py coding), Robin Dunn, Robin Rappin, Mike Driscoll, the wxPython community...


About this page

Date(d/m/y) Person (bot) Comments :

02/03/20 - Ecco (Created page for wxPython Phoenix).

30/03/20 - Ecco (Added, modified and updated examples for wxPython Phoenix).


Comments

- blah, blah, blah....

How to create a virtual list control (Phoenix) (last edited 2020-12-13 13:50:14 by Ecco)

NOTE: To edit pages in this wiki you must be a member of the TrustedEditorsGroup.