📄 grid_megaexample.py
字号:
import wx
import wx.grid as Grid
import images
#---------------------------------------------------------------------------
class MegaTable(Grid.PyGridTableBase):
"""
A custom wx.Grid Table using user supplied data
"""
def __init__(self, data, colnames, plugins):
"""data is a list of the form
[(rowname, dictionary),
dictionary.get(colname, None) returns the data for column
colname
"""
# The base class must be initialized *first*
Grid.PyGridTableBase.__init__(self)
self.data = data
self.colnames = colnames
self.plugins = plugins or {}
# XXX
# we need to store the row length and column length to
# see if the table has changed size
self._rows = self.GetNumberRows()
self._cols = self.GetNumberCols()
def GetNumberCols(self):
return len(self.colnames)
def GetNumberRows(self):
return len(self.data)
def GetColLabelValue(self, col):
return self.colnames[col]
def GetRowLabelValue(self, row):
return "row %03d" % int(self.data[row][0])
def GetValue(self, row, col):
return str(self.data[row][1].get(self.GetColLabelValue(col), ""))
def GetRawValue(self, row, col):
return self.data[row][1].get(self.GetColLabelValue(col), "")
def SetValue(self, row, col, value):
self.data[row][1][self.GetColLabelValue(col)] = value
def ResetView(self, grid):
"""
(Grid) -> Reset the grid view. Call this to
update the grid if rows and columns have been added or deleted
"""
grid.BeginBatch()
for current, new, delmsg, addmsg in [
(self._rows, self.GetNumberRows(), Grid.GRIDTABLE_NOTIFY_ROWS_DELETED, Grid.GRIDTABLE_NOTIFY_ROWS_APPENDED),
(self._cols, self.GetNumberCols(), Grid.GRIDTABLE_NOTIFY_COLS_DELETED, Grid.GRIDTABLE_NOTIFY_COLS_APPENDED),
]:
if new < current:
msg = Grid.GridTableMessage(self,delmsg,new,current-new)
grid.ProcessTableMessage(msg)
elif new > current:
msg = Grid.GridTableMessage(self,addmsg,new-current)
grid.ProcessTableMessage(msg)
self.UpdateValues(grid)
grid.EndBatch()
self._rows = self.GetNumberRows()
self._cols = self.GetNumberCols()
# update the column rendering plugins
self._updateColAttrs(grid)
# update the scrollbars and the displayed part of the grid
grid.AdjustScrollbars()
grid.ForceRefresh()
def UpdateValues(self, grid):
"""Update all displayed values"""
# This sends an event to the grid table to update all of the values
msg = Grid.GridTableMessage(self, Grid.GRIDTABLE_REQUEST_VIEW_GET_VALUES)
grid.ProcessTableMessage(msg)
def _updateColAttrs(self, grid):
"""
wx.Grid -> update the column attributes to add the
appropriate renderer given the column name. (renderers
are stored in the self.plugins dictionary)
Otherwise default to the default renderer.
"""
col = 0
for colname in self.colnames:
attr = Grid.GridCellAttr()
if colname in self.plugins:
renderer = self.plugins[colname](self)
if renderer.colSize:
grid.SetColSize(col, renderer.colSize)
if renderer.rowSize:
grid.SetDefaultRowSize(renderer.rowSize)
attr.SetReadOnly(True)
attr.SetRenderer(renderer)
grid.SetColAttr(col, attr)
col += 1
# ------------------------------------------------------
# begin the added code to manipulate the table (non wx related)
def AppendRow(self, row):
#print 'append'
entry = {}
for name in self.colnames:
entry[name] = "Appended_%i"%row
# XXX Hack
# entry["A"] can only be between 1..4
entry["A"] = random.choice(range(4))
self.data.insert(row, ["Append_%i"%row, entry])
def DeleteCols(self, cols):
"""
cols -> delete the columns from the dataset
cols hold the column indices
"""
# we'll cheat here and just remove the name from the
# list of column names. The data will remain but
# it won't be shown
deleteCount = 0
cols = cols[:]
cols.sort()
for i in cols:
self.colnames.pop(i-deleteCount)
# we need to advance the delete count
# to make sure we delete the right columns
deleteCount += 1
if not len(self.colnames):
self.data = []
def DeleteRows(self, rows):
"""
rows -> delete the rows from the dataset
rows hold the row indices
"""
deleteCount = 0
rows = rows[:]
rows.sort()
for i in rows:
self.data.pop(i-deleteCount)
# we need to advance the delete count
# to make sure we delete the right rows
deleteCount += 1
def SortColumn(self, col):
"""
col -> sort the data based on the column indexed by col
"""
name = self.colnames[col]
_data = []
for row in self.data:
rowname, entry = row
_data.append((entry.get(name, None), row))
_data.sort()
self.data = []
for sortvalue, row in _data:
self.data.append(row)
# end table manipulation code
# ----------------------------------------------------------
# --------------------------------------------------------------------
# Sample wx.Grid renderers
class MegaImageRenderer(Grid.PyGridCellRenderer):
def __init__(self, table):
"""
Image Renderer Test. This just places an image in a cell
based on the row index. There are N choices and the
choice is made by choice[row%N]
"""
Grid.PyGridCellRenderer.__init__(self)
self.table = table
self._choices = [images.getSmilesBitmap,
images.getMondrianBitmap,
images.getWXPdemoBitmap,
]
self.colSize = None
self.rowSize = None
def Draw(self, grid, attr, dc, rect, row, col, isSelected):
choice = self.table.GetRawValue(row, col)
bmp = self._choices[ choice % len(self._choices)]()
image = wx.MemoryDC()
image.SelectObject(bmp)
# clear the background
dc.SetBackgroundMode(wx.SOLID)
if isSelected:
dc.SetBrush(wx.Brush(wx.BLUE, wx.SOLID))
dc.SetPen(wx.Pen(wx.BLUE, 1, wx.SOLID))
else:
dc.SetBrush(wx.Brush(wx.WHITE, wx.SOLID))
dc.SetPen(wx.Pen(wx.WHITE, 1, wx.SOLID))
dc.DrawRectangleRect(rect)
# copy the image but only to the size of the grid cell
width, height = bmp.GetWidth(), bmp.GetHeight()
if width > rect.width-2:
width = rect.width-2
if height > rect.height-2:
height = rect.height-2
dc.Blit(rect.x+1, rect.y+1, width, height,
image,
0, 0, wx.COPY, True)
class MegaFontRenderer(Grid.PyGridCellRenderer):
def __init__(self, table, color="blue", font="ARIAL", fontsize=8):
"""Render data in the specified color and font and fontsize"""
Grid.PyGridCellRenderer.__init__(self)
self.table = table
self.color = color
self.font = wx.Font(fontsize, wx.DEFAULT, wx.NORMAL, wx.NORMAL, 0, font)
self.selectedBrush = wx.Brush("blue", wx.SOLID)
self.normalBrush = wx.Brush(wx.WHITE, wx.SOLID)
self.colSize = None
self.rowSize = 50
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -