You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现wxPython ListCtrl列排序:末列数值排序、前两列文本排序

Fix Numeric Sort for Last Column in wxPython ListCtrl

Got it, the issue here is that the default ColumnSorterMixin treats all column values as strings, so your "year" column gets sorted lexicographically (that's why "11" comes before "2"). To fix this, we need to override how the sorting keys are generated based on which column is being sorted.

Here's the modified code with explanations of the key changes:

import wx
import sys
from wx.lib.mixins.listctrl import ColumnSorterMixin

actresses = {
 1 : ('jessica alba', 'pomona', '1'),
 2 : ('sigourney weaver', 'new york', '2'),
 3 : ('angelina jolie', 'los angeles', '11'),
 4 : ('natalie portman', 'jerusalem', '12'),
 5 : ('rachel weiss', 'london', '20'),
 6 : ('scarlett johansson', 'new york', '22')
}

class SortedListCtrl(wx.ListCtrl, ColumnSorterMixin):
 def __init__(self, parent):
 wx.ListCtrl.__init__(self, parent, -1, style=wx.LC_REPORT)
 # Fix: Pass the number of columns (3) instead of number of items
 ColumnSorterMixin.__init__(self, 3)
 self.itemDataMap = actresses

 def GetListCtrl(self):
 return self

 # Add this method to customize sorting keys per column
 def GetSortKey(self, index, col):
    # Get the text value of the item in the specified column
    item_text = self.GetItem(index, col).GetText()
    # For the last column (year), convert to integer for numeric sorting
    if col == 2:
        return int(item_text)
    # For first two columns, use lowercase text for case-insensitive sort
    # Remove .lower() if you want case-sensitive sorting
    return item_text.lower()

class Actresses(wx.Frame):
 def __init__(self, parent, id, title):
 wx.Frame.__init__(self, parent, id, title, size=(380, 230))
 hbox = wx.BoxSizer(wx.HORIZONTAL)
 panel = wx.Panel(self, -1)
 self.list = SortedListCtrl(panel)
 self.list.InsertColumn(0, 'name', width=140)
 self.list.InsertColumn(1, 'place', width=130)
 self.list.InsertColumn(2, 'year', wx.LIST_FORMAT_RIGHT, 90)
 items = actresses.items()
 for key, data in items:
 index = self.list.InsertStringItem(sys.maxsize, data[0])
 self.list.SetStringItem(index, 1, data[1])
 self.list.SetStringItem(index, 2, data[2])
 self.list.SetItemData(index, key)
 hbox.Add(self.list, 1, wx.EXPAND)
 panel.SetSizer(hbox)
 self.Centre()
 self.Show(True)

if __name__ == '__main__':
 app = wx.App()
 Actresses(None, -1, 'Actresses')
 app.MainLoop()

Key Changes Explained:

  1. Fixed ColumnSorterMixin Initialization:
    The original code passed len(actresses) (which is 6, the number of data items) to ColumnSorterMixin.__init__, but this parameter should be the number of columns (3) so the mixin knows how many columns to handle sorting for.

  2. Added GetSortKey Method:
    This method overrides the default behavior of the mixin. It checks which column is being sorted:

    • For column 2 (year), we convert the string value to an integer, so sorting uses numeric order instead of lexicographical.
    • For columns 0 and 1 (name/place), we return the lowercase text for case-insensitive sorting. Remove .lower() if you want case-sensitive text sorting.

Now when you click the "year" column header, it will sort numerically (2 → 11 → 12 → 20 → 22), while the name and place columns still sort as text.

内容的提问来源于stack exchange,提问作者Max

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 03:52:23