Sorted List Control - how?

Donn Ingle wrote:

The docs show a SortItems() call that does this. (Note it doesn't
"maintain" it for you... you just call that method to ensure it is
sorted whenever you want it to be.)

Thanks, I dunno how I missed that one. I'll go have another look.

The interface for wxPython might be non-obvious, especially to a beginner (not sure if you are one or not). Here's a trivialized example you can probably build on, which should explain what the note about "a callable object" means in the C++ docs:

Define a sorter class, something like this. It exists basically so __call__() can be defined for it:

class _StepSorter(object):
     '''used in call to ListCtrl.SortItems()'''
     def __call__(self, a, b):
         # a and b were set by ListCtrl.SetItemData()
         return cmp(a, b)

# when you insert/add items into the list, call SetItemData for them
# since that's what SortItems() passes to the sorter object:

     index = self.listCtrl.InsertStringItem(0, 'some string')
     self.listCtrl.SetItemData(index, someValue)

     # elsewhere in your code...
     stepSorter = _StepSorter() # could create this once and save

     # now do the sort itself
     self.listCtrl.SortItems(stepSorter)

At this point the list items are sorted according to how your __call__() comparator method in the sorter compares the values passed in, which are the values you passed to SetItemData(). I don't know whether you can pass in values that are not integers, not having tried it, but the docs suggest you won't be able to, so if you wanted to compare the strings themselves (e.g. for alphabetical order) you'd probably need to make someValue the same as index, and index into an array of strings that you'd store elsewhere, or look them up directly with GetItemText() or something. I haven't worked with this feature a lot... just hoping this helps a little. (My list items were basically images with numbers as labels, and I just wanted them sorted numerically so it was simple.)

-Peter

Hi Donn,

Donn Ingle wrote:

A "callable object" doesn't have to be a class with a __call__ method.
It is anything that can be called, IOW, any foo for which foo(a,b) is
possible.
    

Robin,
If all that ca get passed to foo is a and b - which are numbers assigned
during a SetItemData call, how can one achieve an alphabetical sort?

I mean - let's assume everything I put into the listctrl up-front gets the
numbers 1 to 10 as the items go into it; later-on I want to add a new item.
How do I know what number to give the new item such that it will sort into
the listctrl? Let's say the new item should fit between 3 and 4 in the list. How do I know
this?

It seems like I have to keep a separate list, add the new item, sort the
list and then go through it and re-number each item (perhaps each item is
stored in a tuple) and then go through the listcontrol and re-number each
item there (by a SetItemData) from my separate list and then call
SortItems(foo). No?

Feeling thick today :wink:
/d

To me it is magic and it took me some time to figure out the basics of it.

I suggest that you put some print statements into the method __ColumnSorter in lib/mixins/listctrl.py and then run the demo.

You will see that item1 and item2 is the thing being sorted (text, int etc) and the key1 and key2 is the unique value you put into ClientData.

Werner

The key will get mapped to the text to sort by and the item will
get shuffled into place.

Thanks for the help Robin, it's early here and my brain needs to warm up
before I'll get the picture!

/d