wxPython listctrl: allowing sorting for only some columns
<p>I have a table displayed using <code>wx.ListCtrl</code>. I want all the columns to be sortable upon clicking the column headers except for the first column which stores the row index (e.g., 0,1,2,3,...). So that means, if a user clicks on the first column's header, the table should not be sorted. But <code>ColumnSorterMixin</code> seems to only let me specify the number of sortable columns. Since the row id column is the first column, this does not allow me to exclude the row id column from one of the sortable ones. Any suggestion would be much appreciated!</p>

<pre><code>import wx
import wx.lib.mixins.listctrl as listmix

musicdata = {
0 : ("Bad English", "The Price Of Love", "Rock"),
1 : ("DNA featuring Suzanne Vega", "Tom's Diner", "Rock"),
2 : ("George Michael", "Praying For Time", "Rock"),
3 : ("Gloria Estefan", "Here We Are", "Rock"),
4 : ("Linda Ronstadt", "Don't Know Much", "Rock"),
5 : ("Michael Bolton", "How Am I Supposed To Live Without You", "Blues"),
6 : ("Paul Young", "Oh Girl", "Rock"),
}

########################################################################
class TestListCtrl(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)

########################################################################
class TestListCtrlPanel(wx.Panel, listmix.ColumnSorterMixin):

    #----------------------------------------------------------------------
    def __init__(self, parent):
        wx.Panel.__init__(self, parent, -1, style=wx.WANTS_CHARS)

        self.index = 0

        self.list_ctrl = TestListCtrl(self, size=(-1,100),
                         style=wx.LC_REPORT
                         |wx.BORDER_SUNKEN
                         |wx.LC_SORT_ASCENDING
                         )
        self.list_ctrl.InsertColumn(0, "RowID")
        self.list_ctrl.InsertColumn(1, "Artist")
        self.list_ctrl.InsertColumn(2, "Title", wx.LIST_FORMAT_RIGHT)
        self.list_ctrl.InsertColumn(3, "Genre")

        items = musicdata.items()
        self.itemDataMap = dict()
        index = 0
        for key, data in items:
            self.list_ctrl.InsertStringItem(index, str(index+1))
            self.list_ctrl.SetStringItem(index, 1, data[0])
            self.list_ctrl.SetStringItem(index, 2, data[1])
            self.list_ctrl.SetStringItem(index, 3, data[2])
            self.list_ctrl.SetItemData(index, key)
            self.itemDataMap[index] = (str(index), data[0], data[1], data[2])
            index += 1

        # Now that the list exists we can init the other base class,
        # see wx/lib/mixins/listctrl.py
       #self.itemDataMap = musicdata
        listmix.ColumnSorterMixin.__init__(self, 4)
        self.Bind(wx.EVT_LIST_COL_CLICK, self.OnColClick, self.list_ctrl)

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.list_ctrl, 0, wx.ALL|wx.EXPAND, 5)
        self.SetSizer(sizer)

    #----------------------------------------------------------------------
    # Used by the ColumnSorterMixin, see wx/lib/mixins/listctrl.py
    def GetListCtrl(self):
        return self.list_ctrl

    #----------------------------------------------------------------------
    def OnColClick(self, event):
        print "column clicked"
        event.Skip()

########################################################################
class MyForm(wx.Frame):

    #----------------------------------------------------------------------
    def __init__(self):
        wx.Frame.__init__(self, None, wx.ID_ANY, "List Control Tutorial")

        # Add a panel so it looks the correct on all platforms
        panel = TestListCtrlPanel(self)

#----------------------------------------------------------------------
# Run the program
if __name__ == "__main__":
    app = wx.App(False)
    frame = MyForm()
    frame.Show()
    app.MainLoop()
</code></pre>

<p>I don't know if there is a prettier way of handling this. Anyway, following is my approach:</p>

<pre><code>class MyColumnSorterMixin(listmix.ColumnSorterMixin):

    def GetColumnSorter(self):
        if self._col &lt;&gt; 0:
            return listmix.ColumnSorterMixin.GetColumnSorter(self)
</code></pre>

<p>Remember to use the new class, that is <code>MyColumnSorterMixin</code> as in <code>MyColumnSorterMixin.__init__(self, 4)</code></p>

python wxpython listctrl