Reputation: 726
I have this little piece of code and everything is fine for the left ListCtrl:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import wx
import wx.lib.mixins.listctrl as listmix
class FillBD2Frame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, wx.ID_ANY, "FillBD2", size=(400, 300))
self.Centre()
FillBD2(self)
class MyListCtrl(wx.ListCtrl):
def __init__(self, parent, ID=wx.ID_ANY, pos=wx.DefaultPosition, size=wx.DefaultSize, style=0):
wx.ListCtrl.__init__(self, parent, ID, pos, size, style)
self.parent=parent
self.DataMap={}
class FillBD2(wx.Panel, listmix.ColumnSorterMixin):
def __init__(self, parent):
wx.Panel.__init__(self, parent, wx.ID_ANY, style=wx.WANTS_CHARS)
self.parent=parent
self.list_ctrl1=MyListCtrl(self, style=wx.LC_REPORT|wx.BORDER_SUNKEN|wx.LC_SORT_ASCENDING)
self.list_ctrl2=MyListCtrl(self, style=wx.LC_REPORT|wx.BORDER_SUNKEN|wx.LC_SORT_ASCENDING)
self.testen= wx.Button(self, 2, "&test", (-1, -1), wx.DefaultSize)
gr=2
self.list_ctrl1.InsertColumn(0, 'path', width=30*gr)
self.list_ctrl1.InsertColumn(1, 'name', width=30*gr)
self.list_ctrl1.InsertColumn(2, 'size(real)', wx.LIST_FORMAT_RIGHT, width=15*gr)
self.list_ctrl1.InsertColumn(3, 'size(dest)', wx.LIST_FORMAT_RIGHT, width=15*gr)
listmix.ColumnSorterMixin.__init__(self, 4)
self.list_ctrl1.DataMap={
0:("pth1", "nam1", 62, 70),
1:("pth2", "nam2", 22, 30),
2:("pth3", "nam3", 57, 60),
4:("pth4", "nam4", 9, 10)
}
self.fillListCtrl(self.list_ctrl1, 1)
self.list_ctrl2.InsertColumn(0, 'path', width=30*gr)
self.list_ctrl2.InsertColumn(1, 'name', width=30*gr)
self.list_ctrl2.InsertColumn(2, 'size(dest)', wx.LIST_FORMAT_RIGHT, width=15*gr)
# listmix.ColumnSorterMixin.__init__(self, 3)
self.list_ctrl2.DataMap={
0:("pth5", "nam5", 45, 50),
1:("pth6", "nam6", 81, 90),
2:("pth7", "nam7", 33, 40),
4:("pth8", "nam8", 13, 20)
}
self.fillListCtrl(self.list_ctrl2, 2)
self.list_ctrl1.Bind(wx.EVT_LIST_COL_CLICK, self.OnColClick1)
self.list_ctrl2.Bind(wx.EVT_LIST_COL_CLICK, self.OnColClick2)
vsizer=wx.BoxSizer(wx.VERTICAL)
bsizer=wx.BoxSizer(wx.HORIZONTAL)
hsizer=wx.BoxSizer(wx.HORIZONTAL)
bsizer.Add(self.testen, 0, wx.ALL, 5)
hsizer.Add(self.list_ctrl1, 1, wx.ALL|wx.EXPAND, 1)
hsizer.Add(self.list_ctrl2, 1, wx.ALL|wx.EXPAND, 1)
vsizer.Add(bsizer, 0, wx.ALL, 5)
vsizer.Add(hsizer, 1, wx.ALL|wx.EXPAND, 5)
self.SetSizer(vsizer)
vsizer.Fit(self)
self.list_ctrl1.SetFocus()
self.list_ctrl1.Select(0, 1)
def fillListCtrl(self, ctrl, ctrl_nr=1):
ctrl.DeleteAllItems()
ctrl.Refresh()
index=0
for key, data in ctrl.DataMap.items():
ctrl.InsertStringItem(index, data[0])
ctrl.SetStringItem(index, 1, data[1])
ctrl.SetStringItem(index, 2, str(data[2]))
if ctrl_nr==1:
ctrl.SetStringItem(index, 3, str(data[3]))
ctrl.SetItemData(index, key)
index+=1
ctrl.SetItemState(0, wx.LIST_STATE_SELECTED, wx.LIST_STATE_SELECTED)
def GetListCtrl(self):
return(self.list_ctrl1)
def OnColClick1(self, event):
self.itemDataMap=self.list_ctrl1.DataMap
event.Skip()
def OnColClick2(self, event):
self.itemDataMap=self.list_ctrl2.DataMap
event.Skip()
if __name__=='__main__':
app=wx.App()
frame=FillBD2Frame().Show()
app.MainLoop()
But what do I have to do, if I want the right ListCtrl also be sortable?
If I uncomment the second listmix.ColumnSorterMixin.init(), the sorting for the left ListCtrl gets confused and the right one is still not sortable...
And how should the GetListCtrl method decide, which ListCtrl it shall return...!?
Upvotes: 0
Views: 89
Reputation: 33111
You need to refactor the code a bit to get this to work. Since the ColumnSorterMixin requires that the ListCtrl exists (according to the source), it sounds like you need to have the mixin sub-classed with the wx.Panel, creating a class that has inherits from both. Because of this, you need to create a panel that has all the required methods and just a list control as its only widget. Then each time you instantiate this new class, you can add that to your top-level panel. Here's one approach that worked for me:
import wx
import wx.lib.mixins.listctrl as listmix
class FillBD2Frame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, wx.ID_ANY, "FillBD2", size=(400, 300))
self.Centre()
FillBD2(self)
class MyListCtrl(wx.ListCtrl):
def __init__(self, parent, ID=wx.ID_ANY, pos=wx.DefaultPosition, size=wx.DefaultSize, style=0):
wx.ListCtrl.__init__(self, parent, ID, pos, size, style)
self.parent=parent
self.DataMap={}
class FillPanel(wx.Panel, listmix.ColumnSorterMixin):
def __init__(self, parent, DataMap, ctrl_type=1):
wx.Panel.__init__(self, parent, wx.ID_ANY, style=wx.WANTS_CHARS)
self.parent = parent
self.list_ctrl = MyListCtrl(self,
style=wx.LC_REPORT|wx.BORDER_SUNKEN|wx.LC_SORT_ASCENDING)
gr=2
self.list_ctrl.InsertColumn(0, 'path', width=30*gr)
self.list_ctrl.InsertColumn(1, 'name', width=30*gr)
if ctrl_type == 1:
self.list_ctrl.InsertColumn(2, 'size(real)', wx.LIST_FORMAT_RIGHT, width=15*gr)
self.list_ctrl.InsertColumn(3, 'size(dest)', wx.LIST_FORMAT_RIGHT, width=15*gr)
elif ctrl_type == 2:
self.list_ctrl.InsertColumn(2, 'size(dest)', wx.LIST_FORMAT_RIGHT, width=15*gr)
listmix.ColumnSorterMixin.__init__(self, 4)
self.list_ctrl.DataMap = DataMap
self.fillListCtrl(ctrl_type)
self.list_ctrl.Bind(wx.EVT_LIST_COL_CLICK, self.OnColClick)
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(self.list_ctrl, 1, wx.EXPAND)
self.SetSizer(sizer)
def fillListCtrl(self, ctrl_nr=1):
self.list_ctrl.DeleteAllItems()
self.list_ctrl.Refresh()
index=0
for key, data in self.list_ctrl.DataMap.items():
self.list_ctrl.InsertStringItem(index, data[0])
self.list_ctrl.SetStringItem(index, 1, data[1])
self.list_ctrl.SetStringItem(index, 2, str(data[2]))
if ctrl_nr==1:
self.list_ctrl.SetStringItem(index, 3, str(data[3]))
self.list_ctrl.SetItemData(index, key)
index+=1
self.list_ctrl.SetItemState(0, wx.LIST_STATE_SELECTED, wx.LIST_STATE_SELECTED)
def GetListCtrl(self):
return(self.list_ctrl)
def OnColClick(self, event):
self.itemDataMap = self.list_ctrl.DataMap
event.Skip()
class FillBD2(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent, wx.ID_ANY, style=wx.WANTS_CHARS)
self.parent=parent
DataMap_1={
0:("pth1", "nam1", 62, 70),
1:("pth2", "nam2", 22, 30),
2:("pth3", "nam3", 57, 60),
4:("pth4", "nam4", 9, 10)
}
DataMap_2={
0:("pth5", "nam5", 45, 50),
1:("pth6", "nam6", 81, 90),
2:("pth7", "nam7", 33, 40),
4:("pth8", "nam8", 13, 20)
}
self.testen= wx.Button(self, -1, "&test", (-1, -1), wx.DefaultSize)
list_panel = FillPanel(self, DataMap_1)
list_panel_2 = FillPanel(self, DataMap_2, ctrl_type=2)
# create sizers
vsizer = wx.BoxSizer(wx.VERTICAL)
hsizer = wx.BoxSizer(wx.HORIZONTAL)
vsizer.Add(self.testen, 0, wx.ALL, 5)
hsizer.Add(list_panel, 1, wx.ALL|wx.EXPAND, 5)
hsizer.Add(list_panel_2, 1, wx.ALL|wx.EXPAND, 5)
vsizer.Add(hsizer, 1, wx.EXPAND)
self.SetSizer(vsizer)
if __name__=='__main__':
app = wx.App()
frame = FillBD2Frame().Show()
app.MainLoop()
One other thing I need to point out. You had set the button's id to 2, which is a very bad thing. You need to let wxPython manage IDs, especially ones that are below 100 as those tend to be special IDs that wxPython uses internally. To make wxPython dynamically assign an ID, use wx.ID_ANY or -1, as you did in other parts of the code.
Upvotes: 1