文章目录
-
- 典型的 GridTableBase 样例
- 运行图示
- 说明
- 程序代码
典型的 GridTableBase 样例
- wx.grid.GridTableBase 是 wxpython 一个较为常用的控件,这里展示了它的一些用法。
运行图示
一个典型的GridTableBase样例 说明
- 该程序覆盖了 GridTableBase 的3个基本功能,即新增、插入、删除行数据
- 该程序还展示了 grid 样式的一些用法。
程序代码
import wx
import wx.grid
from random import randint
def MakeData(num):
"""生成数据,每一行的格式为 (id, name, date, avail)"""
"""num 表示生成的数据的长度,即总共有多少行数据"""
chars = 'abcdefghijklmnopqrstuvwxyz'
words = []
for _ in range(num):
word = ''
for _ in range(randint(3, 10)):
word += chars[randint(0, 25)]
words.append(word.title())
rows = []
for _ in range(num):
my_date = wx.DateTime(randint(1, 28), randint(0, 11), randint(2000, 2030))
my_date = my_date.FormatISODate()
row = (_ + 1, words[_], my_date, randint(0, 1))
rows.append(row)
return rows
class MyFrame(wx.Frame):
def __init__(self, data):
super().__init__(None, -1, "test grid table's editor", size=(600, 500))
font = self.GetFont()
font.SetPointSize(12)
self.SetFont(font)
panel = wx.Panel(self)
box = wx.BoxSizer(wx.VERTICAL)
tool_bar = wx.ToolBar(panel)
self.grid = MyGrid(panel, data)
box.Add(tool_bar, 1, wx.EXPAND | wx.ALL, 5)
box.Add(self.grid, 1, wx.EXPAND | wx.ALL, 5)
panel.SetSizerAndFit(box)
tool_bar.AddControl(wx.Button(tool_bar, wx.ID_ADD, '增加'))
tool_bar.AddControl(wx.Button(tool_bar, wx.ID_NEW, '插入'))
tool_bar.AddControl(wx.Button(tool_bar, wx.ID_DELETE, '删除'))
tool_bar.Realize()
self.Center()
self.Show()
self.Bind(wx.EVT_BUTTON, self.toolbar_handler)
def toolbar_handler(self, event):
eid = event.GetId()
if eid == wx.ID_ADD:
self.grid.append_row()
elif eid == wx.ID_NEW:
self.grid.insert_row()
elif eid == wx.ID_DELETE:
self.grid.ClearGrid()
class MyGrid(wx.grid.Grid):
def __init__(self, parent, data):
super().__init__(parent)
self.grid_table = GridTable(data)
self.SetTable(self.grid_table, True)
self.avail_index = self.grid_table.col_names.index('avail') # 获取 avail 列的索引号
rows = self.grid_table.GetNumberRows()
cols = self.grid_table.GetNumberCols()
self.AutoSize() # 自动调整列宽和行高
for c in range(cols):
self.SetColSize(c, self.GetColSize(c) + 20) # 每列加宽20个像素
self.SetColFormatNumber(0) # 设置为 整数 格式
self.SetColFormatDate(2, '%Y-%m-%d') # 设置为 日期 格式,并指定日期的格式
self.SetColFormatBool(self.avail_index) # 设置为 布尔 格式,即选定框样式
for r in range(rows): # 设置 avail 列的居中样式
self.SetCellAlignment(r, self.avail_index, wx.ALIGN_CENTRE, wx.ALIGN_CENTRE)
def append_row(self):
self.AppendRows()
self.MakeCellVisible(self.GetNumberRows() - 1, 0) # 在最底下新增一行,所有要使该行显示出来。
def insert_row(self):
row = self.GetGridCursorRow()
self.InsertRows(row)
self.SelectRow(row) # 可以选定该行
def ClearGrid(self):
self.DeleteRows(0, self.GetNumberRows()) # 删除所有行
self.AppendRows(10) # 新增了10行
for row in range(self.GetNumberRows()):
self.SetCellAlignment(row, self.avail_index, wx.ALIGN_CENTER, wx.ALIGN_CENTER)
class GridTable(wx.grid.GridTableBase):
def __init__(self, data):
super().__init__()
self.data = data
self.data = [list(_) for _ in self.data] # 所有数据转化为列表。如果是元组的话不能修改,即不能更改单元格的值。
self.col_names = ['id', 'name', 'date', 'avail']
self.pk_name = self.col_names[0]
def GetCornerLabelValue(self):
return '行号'
def GetColLabelValue(self, col):
return self.col_names[col]
def GetNumberRows(self):
return len(self.data)
def GetNumberCols(self):
return len(self.col_names)
def IsEmptyCell(self, row, col):
return False
def GetValue(self, row, col):
return self.data[row][col]
def SetValue(self, row, col, value):
self.data[row][col] = value
def AppendRows(self, num=1):
for i in range(num): # 数据在 AppendRows 时不会自动增加,所以要在这里增加行数据。
self.data.append([None for _ in self.col_names])
grid_view = self.GetView()
grid_view.BeginBatch()
append_msg = wx.grid.GridTableMessage(self, wx.grid.GRIDTABLE_NOTIFY_ROWS_APPENDED, num)
grid_view.ProcessTableMessage(append_msg)
grid_view.EndBatch()
get_value_msg = wx.grid.GridTableMessage(self, wx.grid.GRIDTABLE_REQUEST_VIEW_GET_VALUES)
grid_view.ProcessTableMessage(get_value_msg)
return True
def InsertRows(self, pos=0, num=1):
for i in range(num):
self.data.insert(pos, [None for _ in self.col_names])
grid_view = self.GetView()
grid_view.BeginBatch()
insert_msg = wx.grid.GridTableMessage(self, wx.grid.GRIDTABLE_NOTIFY_ROWS_INSERTED, pos, num)
grid_view.ProcessTableMessage(insert_msg)
grid_view.EndBatch()
get_value_msg = wx.grid.GridTableMessage(self, wx.grid.GRIDTABLE_REQUEST_VIEW_GET_VALUES)
grid_view.ProcessTableMessage(get_value_msg)
return True
def DeleteRows(self, pos=0, num=1):
if self.data is None or len(self.data) == 0:
return False
grid_view = self.GetView()
grid_view.BeginBatch()
delete_msg = wx.grid.GridTableMessage(self, wx.grid.GRIDTABLE_NOTIFY_ROWS_DELETED, pos, num)
grid_view.ProcessTableMessage(delete_msg)
grid_view.EndBatch()
get_value_msg = wx.grid.GridTableMessage(self, wx.grid.GRIDTABLE_REQUEST_VIEW_GET_VALUES)
grid_view.ProcessTableMessage(get_value_msg)
for i in range(num): # 记得在该位置删除行数据
self.data.pop(pos)
return True
my_data = MakeData(100)
app = wx.App()
frm = MyFrame(my_data)
app.MainLoop()