wxpython grid 表格快速定位及排序
简介
当表格中数据较多时,通常需要对数据进行快速定位及排序,以下程序演示了如何实现这两个功能。
为方便中在其他程序中调用,这两个功能都做成了类中的函数。
功能介绍
- 快速定位
-
- 到顶部
-
- 回退到上一页
-
- 快进到下一页
-
- 到底部
-
- 按列排序
- 左键双击列名进行排序;
- 默认为升序,如果重复双击列名,则在升序、降序中反转。
图例
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIyVGduV2YfNWawNyZuBnL3MzYiVTZiFDMkN2MjhTM5UmN0QTNyEDO0MGM1ITOjZzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
程序代码
import wx.grid
import string
import random
class MyPanel(wx.Panel):
def __init__(self, parent):
super().__init__(parent)
font = self.GetFont()
font.SetPointSize(12)
self.SetFont(font)
self.order_col = [0, False] # 待排序的列索引, 是否逆序
self.grid = wx.grid.Grid(self)
self.data = make_data(100)
self.n_rows = len(self.data)
self.col_names = ['编号', '姓名', '生日', '有效性']
self.n_cols = len(self.col_names)
self.on_init()
self.Bind(wx.grid.EVT_GRID_LABEL_LEFT_DCLICK, self.label_left_dclick) # 双击列名,进行排序
def on_init(self):
box = wx.BoxSizer(wx.VERTICAL)
panel_fast = wx.Panel(self)
GridTools(self.grid).fast_move_bar(panel_fast) # 加入表格数据快进按钮
box.Add(panel_fast, 0, wx.ALL, 5)
box.Add(self.grid, 1, wx.EXPAND | wx.ALL, 5)
self.SetSizerAndFit(box)
self.grid.CreateGrid(self.n_rows, self.n_cols)
for col in range(self.n_cols):
self.grid.SetColLabelValue(col, self.col_names[col])
for row in range(self.n_rows):
for col in range(self.n_cols):
self.grid.SetCellValue(row, col, str(self.data[row][col]))
if col == self.col_names.index('有效性'):
self.grid.SetCellAlignment(row, col, wx.ALIGN_CENTER, wx.ALIGN_CENTER)
self.grid_style()
def grid_style(self):
self.grid.SetColFormatNumber(0)
self.grid.SetColFormatDate(2, "%Y-%m-%d")
self.grid.SetColFormatBool(3)
self.grid.AutoSizeColumns()
for col in range(self.n_cols):
self.grid.SetColSize(col, self.grid.GetColSize(col) + 10)
def label_left_dclick(self, _):
self.order_col = GridTools(self.grid).order_grid(self.order_col)
class GridTools:
def __init__(self, grid: wx.grid.Grid):
self.grid = grid
def get_grid_data(self):
grid_data = []
for row in range(self.grid.GetNumberRows()):
row_data = []
for col in range(self.grid.GetNumberCols()):
row_data.append(self.grid.GetCellValue(row, col))
grid_data.append(row_data)
return grid_data
def show_grid(self, data):
"""在表格中显示 data"""
for row in range(self.grid.GetNumberRows()):
for col in range(self.grid.GetNumberCols()):
self.grid.SetCellValue(row, col, str(data[row][col]))
def fast_move_bar(self, parent_panel):
"""快速移动表格定位,快进、快退以表格页面为单位。"""
panel = wx.Panel(parent_panel)
fast_btn = [wx.Button(panel, wx.ID_TOP, '|<'), wx.Button(panel, wx.ID_BACKWARD, '<<'),
wx.Button(panel, wx.ID_FORWARD, '>>'), wx.Button(panel, wx.ID_BOTTOM, '>|')]
box = wx.BoxSizer()
box.AddMany(fast_btn)
panel.SetSizerAndFit(box)
def btn_handler(event):
eid = event.GetId()
if eid == wx.ID_TOP:
self.grid.GoToCell(0, 0)
elif eid == wx.ID_BACKWARD:
self.grid.MovePageUp()
elif eid == wx.ID_FORWARD:
self.grid.MovePageDown()
elif eid == wx.ID_BOTTOM:
self.grid.GoToCell(self.grid.GetNumberRows()-1, 0)
panel.Bind(wx.EVT_BUTTON, btn_handler)
def order_grid(self, last_col: list):
"""双击列名以排序, last_col: 上次排序的列的索引号、是否逆序,如 [0, False]"""
clicked_col = self.grid.GetGridCursorCol()
if clicked_col == last_col[0]:
last_col[1] = not last_col[1] # 如果列索引相同,则顺序反转
grid_data = self.get_grid_data()
grid_data.sort(key=lambda x: x[clicked_col], reverse=last_col[1])
self.show_grid(grid_data)
return [clicked_col, last_col[1]]
def make_data(n=10):
"""产生随机数据"""
data = []
for i in range(n):
my_id = i + 1
name = ''
for _ in range(random.randint(3, 10)):
name += string.ascii_lowercase[random.randint(0, 25)]
name = name.title()
date = wx.DateTime.FromDMY(1, 0, 1990) + wx.DateSpan(days=random.randint(0, 365*20))
birthday = wx.DateTime.FormatISODate(date)
avail = '1' if random.randint(0, 1) else ''
data.append((my_id, name, birthday, avail))
return data
if __name__ == '__main__':
app = wx.App()
frm = wx.Frame(None, -1, 'grid 快进及排序', size=(600, 500))
MyPanel(frm)
frm.Center()
frm.Show()
app.MainLoop()