Hello,
here is the code of an example that causes wxPython to crash. The GridCellAttr instances which I create get cleaned up somewhere, although their Python wrapper still exists.
And I don't know how I can prevent them from being cleaned up.
The programm starts to paint the grid, and the print statements in GetAttr() print "wxPython wrapper for DELETED wxGridCellAttr object! (The C++ object no longer exists.)"
I saw the entry "Prevent access to dead windows" in Robin's todo-list
http://alldunn.com/wxPython/todo/notes224.html
I hope that my code is useful to help finding a solution for this issue.
import wx
import wx.grid
class Report:
def __init__(self):
self.rows = []
self.rows.append((1,"Luc","Eupen"))
self.rows.append((2,"Lennart","Tallinn"))
self.rows.append((3,"Bill","Redmont"))
self.columns = []
self.columns.append("Id")
self.columns.append("Name")
self.columns.append("Town")
def getLabel(self):
return "Famous people"
class MyDataTable(wx.grid.PyGridTableBase):
def __init__(self, report):
wx.grid.PyGridTableBase.__init__(self)
self.report = report
self.columns = report.columns
self.rows = report.rows
self.cellattrs = []
for col in self.columns:
cellattr = wx.grid.GridCellAttr()
cellattr.SetEditor(wx.grid.GridCellTextEditor())
cellattr.SetRenderer(
wx.grid.GridCellStringRenderer())
self.cellattrs.append(cellattr)
def GetNumberRows(self): return len(self.rows) + 1
def GetNumberCols(self): return len(self.columns)
def GetValue(self, rowIndex, colIndex):
try:
return self.rows[rowIndex][colIndex]
except IndexError:
return None
def GetAttr(self,r,c,x):
"overridden to handle attributes directly in the table"
print "GetAttr(%d,%d,%d) -> %s" %
(r, c, x, repr(self.cellattrs[c]))
return self.cellattrs[c]
def GetColLabelValue(self, col):
"Called when the grid needs to display labels"
return self.columns[col]
class RptGrid(wx.grid.Grid):
def __init__(self, parent, report):
wx.grid.Grid.__init__(self, parent, -1)
table = MyDataTable(report)
self.SetTable(table,True)
self.SetRowLabelSize(0)
self.SetMargins(0,0)
#self.AutoSizeColumns(True)
class RptFrame(wx.Frame):
def __init__(self, parent, id, report):
title = report.getLabel()
wx.Frame.__init__(self, parent, id, title)
self.grid = RptGrid(self,report)
class MyApp(wx.App):
def __init__(self,report):
self.report = report
wx.App.__init__(self,0)
def OnInit(self):
wx.InitAllImageHandlers()
frame = RptFrame(None,-1,self.report)
frame.Show()
self.SetTopWindow(frame)
return True
if __name__ == '__main__':
report = Report()
app = MyApp(report)
app.MainLoop()
best regards
Luc Saffre
···
--
In theory, there is no difference between theory and practice.
In practice, there is.