Reputation: 53
I have a data in dictionary which will go to ListCtrl. I have checkboxes listmix.CheckListCtrlMixin for selecting data and listmix.ColumnSorterMixin for sorting.
The problem is that after I sorted data by any column the original order of data is changed and after checking items I can't find the data for further action.
Is it possible to get new "after sorting" dict or something like that?
Here's the demo example.
import sys
import wx
import wx.lib.mixins.listctrl as listmix
musicdata = {
1 : ( 'Bad English', 'The Price Of Love', 'Rock' ),
2 : ( 'Michael Bolton', 'How Am I Supposed To Live Without You', 'Blues' ),
3 : ( 'Paul Young', 'Oh Girl', 'Rock' ),
4 : ( 'Paula Abdul', 'Opposites Attract', 'Rock' ),
5 : ( 'Richard Marx', 'Should\'ve Known Better', 'Rock' ),
6 : ( 'Rod Stewart', 'Forever Young', 'Rock' ),
7 : ( 'Roxette', 'Dangerous', 'Rock' ),
}
class TestListCtrl( wx.ListCtrl, listmix.ListCtrlAutoWidthMixin, listmix.CheckListCtrlMixin ) :
def __init__( self, parent, ID, pos=wx.DefaultPosition,
size=wx.DefaultSize, style=0 ) :
wx.ListCtrl.__init__( self, parent, ID, pos, size, style )
listmix.ListCtrlAutoWidthMixin.__init__( self )
listmix.CheckListCtrlMixin.__init__(self)
self.Bind(wx.EVT_LIST_COL_CLICK, self.OnCheckItem)
def OnCheckItem(self, data, flag):
print(data, flag)
class TabPanel( wx.Panel, listmix.ColumnSorterMixin ) :
def __init__( self, parent ) :
wx.Panel.__init__( self, parent=parent, id=wx.ID_ANY )
self.createAndLayout()
def createAndLayout( self ) :
sizer = wx.BoxSizer( wx.VERTICAL )
self.list = TestListCtrl( self, wx.ID_ANY, style=wx.LC_REPORT
| wx.BORDER_NONE
| wx.LC_EDIT_LABELS
| wx.LC_SORT_ASCENDING )
sizer.Add( self.list, 1, wx.EXPAND )
self.populateList()
self.itemDataMap = musicdata
listmix.ColumnSorterMixin.__init__( self, 3 )
self.SetSizer( sizer )
self.SetAutoLayout( True )
def populateList( self ) :
self.list.InsertColumn( 0, 'Artist' )
self.list.InsertColumn( 1, 'Title', wx.LIST_FORMAT_RIGHT )
self.list.InsertColumn( 2, 'Genre' )
items = musicdata.items()
for key, data in items :
index = self.list.InsertStringItem( sys.maxint, data[ 0 ] )
self.list.SetStringItem( index, 1, data[ 1 ] )
self.list.SetStringItem( index, 2, data[ 2 ] )
self.list.SetItemData( index, key )
self.list.SetColumnWidth( 0, wx.LIST_AUTOSIZE )
self.list.SetColumnWidth( 1, wx.LIST_AUTOSIZE )
self.list.SetColumnWidth( 2, 100 )
self.list.SetItemState( 5, wx.LIST_STATE_SELECTED, wx.LIST_STATE_SELECTED )
self.currentItem = 0
def GetListCtrl( self ) :
return self.list
class DemoFrame( wx.Frame ) :
def __init__( self ) :
wx.Frame.__init__( self, None, wx.ID_ANY, title="Panel Tutorial",
size=(600, 300) )
panel = TabPanel( self )
self.Show()
app = wx.App()
frame = DemoFrame()
app.MainLoop()
Upvotes: 1
Views: 1192
Reputation: 2295
As the answer to this question :Sort a Python dictionary by value shows, it is not possible to sort a dict, only to get a representation of a dict that is sorted.
You can obtain the list of items in a sorted order after clicking on one of the column headers by defining a function in class TestListCtrl
like this:
class TestListCtrl( wx.ListCtrl, listmix.ListCtrlAutoWidthMixin, listmix.CheckListCtrlMixin ) :
def __init__( self, parent, ID, pos=wx.DefaultPosition,
size=wx.DefaultSize, style=0 ) :
wx.ListCtrl.__init__( self, parent, ID, pos, size, style )
listmix.ListCtrlAutoWidthMixin.__init__( self )
listmix.CheckListCtrlMixin.__init__(self)
self.Bind(wx.EVT_LIST_COL_CLICK, self.OnCheckItem)
self.Binf(wx.EVT_LIST_COL_CLICK, self.GetSortedOrder)
def OnCheckItem(self, data, flag):
print(data, flag)
def GetSortedOrder(self, event):
count = self.GetItemCount()
self.sorted_artists = [self.GetItem(itemId=row, col=0).GetText() for row in xrange(count)]
print self.sorted_artists
The method GetSortedOrder()
will create a sorted_artists
attribute which is a list of the artists in the sorted order updated every time you click any of the column headers. You can get other values such as Title or Genre by changing the name of the column. Use this to compare against the original dict and create a new dict if you want
Upvotes: 1