== Introduction == Sorting what's in a List Control can be a little frustrating. Here is a short example of the basic idea. I hope this help someone. == What Objects are Involved == * wx.ListCtrl * locale, os == Process Overview == The basic idea is that you keep a local dictionary of the data that appears ''again'' in the list. This is an uncomfortable thought for a lot of programmers, but it's the only way to handle the situation. The keys to this local data are also recorded within the list items (or in the List Control somewhere) so that there is a link between what's ''inside'' the List control and what's inside your local data dict. When SortItems is called, the List Control is parsed in twos; two items, identified by a number, are sent to your custom comparison function. These two numbers are taken directly from what you dictate in the SetItemData command. You can therefore lookup the string from your locale dict by using those numbers. I'll let the code finish the talking. Notice the fancy opening line - that signals to Python that utf8 characters are to be expected in the source code file. It's actually the encoding of the file contents and without it you cannot hope to insert really bizarre characters. (Bizarre for a Westener :) ) == Code Sample == {{{ #!python # -*- coding:utf-8 -*- import os import locale import wx # Set the locale to whatever it's supposed to be: locale.setlocale ( locale.LC_ALL,'') tmp = [] path = "." tmp = os.listdir ( path ) # Some gibberish and words in Swedish (which I don't speak) pulled randomly from the net. tests = ["åÅÅÅ","ÄÄÄb","Cö","ÖÖ","A","a","z","Z", "Mordred","Morgul", "äkta", "blåögd", "hjälplös", "märklig", "ödmjuk", "självbelåten", "utanför", "välsignad" ] # Our wx.ListCtrl class CFilelist ( wx.ListCtrl ) : def __init__ ( self, parent ) : wx.ListCtrl.__init__ ( self,parent,-1, style=wx.LC_LIST | wx.LC_AUTOARRANGE | wx.LC_SORT_ASCENDING ) # Create a local dictionary to keep the words # This *is* double storage of the data, but # there seems to be no better way. self.d = {} for filename in tmp: id = wx.NewId() # make a unique number. self.d[id] = filename # link that to the filename. li = wx.ListItem() # I make an item, there are other methods. li.SetText ( filename ) # plug in the filename, here the data doubles. row = self.InsertItem( li ) # get a row back while we add li to self. self.SetItemData( row, long(id) ) # Associate our id with that row. # Custom sorting function def stepSorter (self, int1, int2): # Get string vals from my dict. # int1 and int2 come directly from SetItemData # of the couple of ListItems that are being sorted. # They are the id's we supplied in __init__ val1 = self.d[int1] # get the filename from our local store val2 = self.d[int2] # use locale to compare them according to the collation # (fancy word that means sorting) of the language we are in. return locale.strcoll( val1, val2 ) # Makes a new item and adds it to the list. def newitem ( self, txt ): li = wx.ListItem ( ) li.SetText (txt) row = self.InsertItem ( li ) id = wx.NewId() self.d[id] = txt # Again, we link the data to our new id self.SetItemData ( row, long(id) ) # Again, assoc. the row with that id. # Sort the list by using our custom function: self.SortItems ( self.stepSorter ) # Just something to show: class CDlg ( wx.Dialog ): def __init__ ( self, parent ): wx.Dialog.__init__ ( self, parent,-1, "files", pos = wx.DefaultPosition )#, size = ( 450,-1) ) self.fl = CFilelist ( self ) self.b = wx.Button ( self, -1, "press") self.b.Bind(wx.EVT_LEFT_UP,self.go) self.s = wx.BoxSizer(wx.VERTICAL) self.s.Add (self.fl,1,wx.GROW) self.s.Add (self.b,0,wx.GROW) self.SetSizer (self.s) self.i = 0 # index into our tests array def go (self,e): print "button pressed - testing the sortorder" self.i += 1 # no bounds test done, my bad. self.fl.newitem (tests[self.i]) # Kick this puppy off. App = wx.App() win = wx.Frame( None ) dlg = CDlg ( win ) dlg.ShowModal ( ) dlg.Destroy ( ) }}} === Comments ===