[wxPython] wxGrid crash when data refreshed

Is there anything special that needs to be done before replacing data
values in a grid after cells have had attributes set and/or renderers
defined? In the following example, based on the SimpleGrid demo,
attempting to refresh the data, by clicking any column header, causes an
access violation.

Using wxPython 2.3.3pre5u-Py22-hybrid and Windows 2000

···

#----------------------------------------------------------

from wxPython.wx import *
from wxPython.grid import *

#----------------------------------------------------------

class SimpleGrid(wxGrid):
  def __init__(self, parent, log):
    wxGrid.__init__(self, parent, -1)

    self.readonly = wxGridCellAttr()
    self.readonly.SetReadOnly(1)
    self.readonly.SetBackgroundColour(wxGREEN)
    self.readwrite = wxGridCellAttr()
    self.readwrite.SetReadOnly(0)
    self.readwrite.SetBackgroundColour(wxWHITE)

    edit0 = wxGridCellChoiceEditor(['MW5','TWO', 'THREE'])
    edit1 = wxGridCellTextEditor()
    edit2 = wxGridCellFloatEditor()
    self.editor = (edit0, edit1, edit2)
    rend0 = wxGridCellStringRenderer()
    rend1 = wxGridCellStringRenderer()
    rend2 = wxGridCellFloatRenderer(6,2)
    self.renderer = (rend0, rend1, rend2)
    
    numrows = 10
    numcols = 4
    colsize = [60, 60, 60, 300]
    colhead = ['Source', 'RefNo', 'Weight', 'Food or ingredient' ]
    self.CreateGrid(numrows, numcols )
    font = self.GetLabelFont()
    font.SetWeight(wxNORMAL)
    self.SetLabelFont(font)
    self.SetRowLabelSize(0)
    for n in range(numrows):
      self.SetRowSize(n,18)
    self.SetColLabelSize(18)
    for n in range(len(colsize)):
      self.SetColSize(n, colsize[n])
      self.SetColLabelValue(n, colhead[n])
    self.SetMargins(0,0)
    self.ShowFoods()
    
    EVT_GRID_LABEL_LEFT_CLICK(self, self.OnGridLabelLeftClick)
    
  def OnGridLabelLeftClick(self, evt):
    self.ShowFoods()
    
  def ShowFoods(self):
    "Show list of ingredients. Make user-editable section read-write "
    self.ClearGrid()
    ngrlist = [ ('MW5', '00123', '25.00', 'Swiss rolls'),
                 ('MW5', '00276', '120.00', 'Custard, with whole milk'),
                 ('MW5', '00298', '270.00', 'Egg fried rice'),
                 ('MW5', '00456', '115.00', 'Pigeon, roast'),
                 ('MW5', '00535', '160.00', 'Steak and kidney pie')]
    nrows = len(ngrlist)
    for row in range(nrows+1):
      self.SetRowAttr(row,self.readwrite)
      for col in range(4):
        if col < 3:
          self.SetCellRenderer(row, col, self.renderer[col])
          self.SetCellEditor(row, col, self.editor[col])
        if row < nrows:
          self.SetCellValue(row, col, ngrlist[row][col])
    for row in range(nrows+1, self.GetNumberRows()):
      self.SetRowAttr(row,self.readonly)
    self.SetColAttr(3,self.readonly)
    self.SetGridCursor(nrows,0)
    
#-----------------------------------------------------------------------

class TestFrame(wxFrame):
  def __init__(self, parent, log):
    wxFrame.__init__(self, parent, -1, "Simple Grid Demo", size=(640,480))
    grid = SimpleGrid(self, log)

#------------------------------------------------------------------------

if __name__ == '__main__':
  import sys
  app = wxPySimpleApp()
  frame = TestFrame(None, sys.stdout)
  frame.Show(true)
  app.MainLoop()

#-------------------------------------------------------------------------

Is there anything special that needs to be done before replacing data
values in a grid after cells have had attributes set and/or renderers
defined? In the following example, based on the SimpleGrid demo,
attempting to refresh the data, by clicking any column header, causes an
access violation.

When you create and save wxGridCellAttrs, wxGridCellEditors or
wxGridCellRenderers to be used and reused later, then you need to call their
IncRef method after each use. Each is created with a ref count of 1 and the
various grid methods that take an attr, editor or renderer assume that they
own that one reference, so if you use it more than once you need to
increment the reference count each time.

···

--
Robin Dunn
Software Craftsman
http://wxPython.org Java give you jitters? Relax with wxPython!