Hello,
I had struggled for hour.
So I decided to take the listctrl from demo,
modify it and try again; the same error.
If you click on the first column header,
the sorting is ok.
Several times clicking on it: sort ascending, descending ... ok.
Then clicking on the second column header.
The first time it seems ok, but
if you click here several times, the sorting gets confused.
You see it especially on the red line, which moves almost
randomly.
Please no comment about the programming style,
it was a rush job 
What did I make wrong?
Many thanks!
#-------begin sample code
import wx
musicdata = {
1 : ("Bad English", "The Price Of Love", "Rock"),
2 : ("DNA featuring Suzanne Vega", "Tom's Diner", "Rock"),
3 : ("George Michael", "Praying For Time", "Rock"),
4 : ("Gloria Estefan", "Here We Are", "Rock"),
5 : ("Linda Ronstadt", "Don't Know Much", "Rock"),
6 : ("Michael Bolton", "How Am I Supposed To Live Without You",
"Blues"),
7 : ("Paul Young", "Oh Girl", "Rock"),
8 : ("Paula Abdul", "Opposites Attract", "Rock"),
9 : ("Richard Marx", "Should've Known Better", "Rock"),
}
class TestListCtrl(wx.ListCtrl):
def __init__(self, parent, ID, pos=wx.DefaultPosition,
size=wx.DefaultSize, style=0):
wx.ListCtrl.__init__(self, parent, ID, pos, size, style)
class TestListCtrlFrame(wx.Frame):
def __init__(self, parent, id, title):
wx.Frame.__init__(self, parent, id, title)
panel = TestListCtrlPanel1 (self)
class TestListCtrlPanel1(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent, -1, style=wx.WANTS_CHARS)
tID = wx.NewId()
self.list = TestListCtrl(self, tID,
style=wx.LC_REPORT
> wx.SUNKEN_BORDER
)
self.PopulateList()
self.itemDataMap = musicdata
self.oldsortcolumn = -1
self.sort_asc = True
self.Bind(wx.EVT_LIST_COL_CLICK, self.OnHeaderClick, self.list)
self.Bind(wx.EVT_SIZE, self.OnSize)
def PopulateList(self):
# but since we want images on the column header we have to do it the
hard way:
info = wx.ListItem()
info.m_mask = wx.LIST_MASK_TEXT | wx.LIST_MASK_IMAGE |
wx.LIST_MASK_FORMAT
info.m_image = -1
info.m_format = 0
info.m_text = "Artist"
self.list.InsertColumnInfo(0, info)
info.m_format = wx.LIST_FORMAT_RIGHT
info.m_text = "Title"
self.list.InsertColumnInfo(1, info)
info.m_format = 0
info.m_text = "Genre"
self.list.InsertColumnInfo(2, info)
items = musicdata.items()
for x in range(len(items)):
key, data = items[x]
self.list.InsertStringItem(x, data[0])
self.list.SetStringItem(x, 1, data[1])
self.list.SetStringItem(x, 2, data[2])
self.list.SetItemData(x, x)
self.list.SetColumnWidth(0, wx.LIST_AUTOSIZE)
self.list.SetColumnWidth(1, wx.LIST_AUTOSIZE)
self.list.SetColumnWidth(2, 100)
# show how to select an item
self.list.SetItemState(5, wx.LIST_STATE_SELECTED,
wx.LIST_STATE_SELECTED)
# show how to change the colour of a couple items
item = self.list.GetItem(1)
item.SetTextColour(wx.BLUE)
self.list.SetItem(item)
item = self.list.GetItem(4)
item.SetTextColour(wx.RED)
self.list.SetItem(item)
self.currentItem = 0
def OnHeaderClick(self, event):
self.nCol = event.GetColumn()
self.SortHeader()
event.Skip()
def SortHeader(self):
if self.oldsortcolumn != self.nCol:
self.sort_asc = True
self.oldsortcolumn = self.nCol
else:
self.sort_asc = not self.sort_asc
self.list.SortItems(self.columnSorter)
#nItem = self.ResultList.GetNextItem(-1, wx.LIST_NEXT_ALL,
wx.LIST_STATE_SELECTED)
#self.ResultList.EnsureVisible(nItem)
def getColumnText(self, index, col):
item = self.list.GetItem(index, col)
return item.GetText()
def columnSorter(self, key1, key2):
if not self.sort_asc:
key1, key2 = key2, key1
item1 = self.getColumnText (key1, self.nCol)#.lower()
item2 = self.getColumnText (key2, self.nCol)#.lower()
if item1 == item2:
return 0
elif item1 < item2:
return -1
else:
return 1
def OnSize(self, event):
w,h = self.GetClientSizeTuple()
self.list.SetDimensions(0, 0, w, h)
class MyFrame(wx.Frame):
def __init__(self, parent, id, title):
wx.Frame.__init__(self, parent, id, title, wx.DefaultPosition,
wx.DefaultSize, wx.DEFAULT_DIALOG_STYLE | wx.MAXIMIZE_BOX |
wx.THICK_FRAME | wx.RESIZE_BORDER)
#self.Panel = TestListCtrlFrane(self, 102, "")
#self.Panel.Show()
self.Panel = TestListCtrlPanel1(self)
class DrApp(wx.App):
def OnInit(self):
frame = MyFrame(None, 101, "MyFrame")
frame.Show(True)
self.SetTopWindow(frame)
return True
if __name__ == '__main__':
app = DrApp(0)
app.MainLoop()
#end sample code
···
--
Franz Steinhäusler
DrPython (Project Developer)
http://drpython.sourceforge.net/
http://sourceforge.net/projects/drpython/