Hello,
I’m having some small problems with the virtual grid. I’m using the basically the same code in my program as found in the Grid_HugeTable demo. I’ve printed my gridtable module below and I’ve got two questions… BTW, thanks for the help, it’s much appreciated!
- I create my virtual grid, using the bit of code below.
import GridTable
self.grid = GridTable.MegaGrid(self, table, column_labels, {})
.
Then, if I want to replace the current grid with a new table can I just use the below line and expect everything to work ok?
self.grid1.SetTable(GridTable.HugeTable(self.GetTable(var), var.GetKeys(), {}))
When is it necessary to use ResetView()?
- My second problem is
that I want to set the background color of a row based on the row label value. The background colors are set using the _updateRowAttr() method in my table class. It works well on creation, but I can’t seem to get it to update when I reset a row label value. I thought that perhaps I needed to use the RefreshView() method to redraw it, I tried this but the code says there is no BeginBatch() for the grid when it reaches grid.BeginBatch() in the RefreshView() method. I’m not sure what BeginBatch() is or how to solve this problem.
here is the bit of code that I’m struggling with to set the background colors.
def OnDisableItem(self, var, index):
self.grid.SetRowLabelValue(index, ‘x,x’)
below is the module for creating the ‘virtual table’ similar to the demo (hugetable or megatable), I called it
‘GridTable.py’
import wx
import wx.grid as gridlib
···
#---------------------------------------------------------------------------
class HugeTable(gridlib.PyGridTableBase):
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
gridlib.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()
self.odd=gridlib.GridCellAttr()
self.odd.SetBackgroundColour("sky blue")
self.even=gridlib.GridCellAttr()
self.even.SetBackgroundColour("sea green")
self.none=gridlib.GridCellAttr()
self.none.SetBackgroundColour(“grey”)
def GetAttr(self, row, col, kind):
value = self.GetRowLabelValue(row).split(',')[0]
if value == 'x':
attr = self.none
else:
attr = [self.even, self.odd][int(value) % 2]
attr.IncRef()
return attr
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 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):
“”"
(gridlib) -> 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(), gridlib.GRIDTABLE_NOTIFY_ROWS_DELETED, gridlib.GRIDTABLE_NOTIFY_ROWS_APPENDED),
(self._cols, self.GetNumberCols(), gridlib.GRIDTABLE_NOTIFY_COLS_DELETED, gridlib.GRIDTABLE_NOTIFY_COLS_APPENDED),
]:
if new <
current:
msg = gridlib.GridTableMessage(self,delmsg,new,current-new)
grid.ProcessTableMessage(msg)
elif new > current:
msg = gridlib.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)
self._updateRowAttrs(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 = gridlib.GridTableMessage(self, gridlib.GRIDTABLE_REQUEST_VIEW_GET_VALUES)
grid.ProcessTableMessage(msg)
def _updateRowAttrs(self, grid):
“”"
wx.Grid -> update the row attributes
“”"
for row in range(self.GetNumberRows()):
grid.SetRowAttr(row, self.GetAttr(row, None, None))
grid.SetRowAttr(row, self.odd)
self.ResetView(self)
def _updateColAttrs(self, grid):
"""
wx.gridlib -> 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 = gridlib.GridCellAttr()
if colname in self.plugins:
renderer = self.pluginscolname
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, subgroup_index, sample_index, entry):
self.data.append(['i,j'%(subgroup_index, sample_index), 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
#---------------------------------------------------------------------------
class
MegaGrid(gridlib.Grid):
def init(self, parent, data, colnames, plugins):
gridlib.Grid.init(self, parent, -1)
self._table = HugeTable(data, colnames, plugins)
The second parameter means that the grid is to take ownership of the
# table and will destroy it when done. Otherwise you would need to keep
# a reference to it and call it's Destroy method later.
self.SetTable(self._table, True)
def Reset(self):
“”“reset the view based on the data in the table. Call
this when rows are added or
destroyed”""
self._table.ResetView(self)
def SetRowBackgroundColor(self, row):
for col in range(self.GetNumberCols()):
value = self.GetRowLabelValue(row)[0]
if value != ‘x’:
self.SetCellBackgroundColour(row, col, [‘sea green’, ‘sky blue’][int(value) % 2])
else:
self.SetCellBackgroundColour(row, col, ‘grey’)
Need a vacation? Get great deals to amazing places on Yahoo! Travel.