I'm trying to create a special widget that is a Grid and also a
PyGridTableBase. In my special case of application, I really need to
have a grid that uses itself for getting cell data and cell
attributes.
Here is a test program, demonstrating my problem:
import wx
from wx.grid import Grid,PyGridTableBase
class SpecialGrid(Grid,PyGridTableBase):
def __init__(self,*args,**kwargs):
PyGridTableBase.__init__(self)
Grid.__init__(self,*args,**kwargs)
self.SetTable(self)
def SetTable(self,table):
if table is not self:
raise Exception("Grid must be its own table!")
else:
PyGridTableBase.SetTable(self,self,takeOwnership=False)
app=wx.App(redirect=None)
frame=wx.Frame(None)
g = SpecialGrid(parent=frame)
sizer = wx.BoxSizer(wx.HORIZONTAL)
sizer.Add(g,1,wx.EXPAND)
frame.SetSizer(sizer)
frame.Show()
frame.Maximize()
app.MainLoop()
This program throws:
Traceback (most recent call last):
File "test.py", line 18, in <module>
g = SpecialGrid(parent=frame)
File "test.py", line 6, in __init__
PyGridTableBase.__init__(self)
File "/usr/lib/python2.7/dist-packages/wx-2.8-gtk2-unicode/wx/
grid.py", line 910, in __init__
self._setOORInfo(self);PyGridTableBase._setCallbackInfo(self,
self, PyGridTableBase)
File "/usr/lib/python2.7/dist-packages/wx-2.8-gtk2-unicode/wx/
_core.py", line 3886, in _setOORInfo
val = _core_.EvtHandler__setOORInfo(*args, **kwargs)
TypeError: in method 'EvtHandler__setOORInfo', expected argument 1 of
type 'wxEvtHandler *'
This makes no sense to me. If I swap the constructor calls:
def __init__(self,*args,**kwargs):
Grid.__init__(self,*args,**kwargs)
PyGridTableBase.__init__(self)
self.SetTable(self)
Then I get this:
Traceback (most recent call last):
File "test.py", line 18, in <module>
g = SpecialGrid(parent=frame)
File "test.py", line 7, in __init__
PyGridTableBase.__init__(self)
File "/usr/lib/python2.7/dist-packages/wx-2.8-gtk2-unicode/wx/
grid.py", line 910, in __init__
self._setOORInfo(self);PyGridTableBase._setCallbackInfo(self,
self, PyGridTableBase)
File "/usr/lib/python2.7/dist-packages/wx-2.8-gtk2-unicode/wx/
_core.py", line 3887, in _setOORInfo
args[0].this.own(False)
File "/usr/lib/python2.7/dist-packages/wx-2.8-gtk2-unicode/wx/
_core.py", line 14586, in __getattr__
raise PyDeadObjectError(self.attrStr % self._name)
wx._core.PyDeadObjectError: The C++ part of the SpecialGrid object has
been deleted, attribute access no longer allowed.
What the heck?
Background information: this special grid has special renderers that
create multiple labels for the grid for every row and column. The
styles of these "extra" labels are controlled by several methods The
data that is needed to build the header labels are implemented with
several data access methods. Within the same grid, different cells
need to have different styles, depending on various conditions that
I'm not going to explain here. Unfortunately, cell level data access
and attribute access methods are defined in PyGridTableBase. So there
are methods that are used for styling and the methods that are used
for virtual data table implementation. They are mixed in two classes:
Grid and PyGridTableBase. My goal is to create mixin classes that can
implement "styling" and "data access" in different ways. For example,
one mixin class that does styling by a CSS file. Another class that
does styling by special attributes stored in a file etc. But because
style/attribute access methods are defined in both Grid and
PyGridTableBase, first I need to create a special grid class that
uses itself as its table, and has all methods from both Grid and
PyGridTableBase (plus the ones needed for the extra renderers).
How do I do that? Apparently, inheriting from Grid + PyGridTableBase
doesn't work.
Pseudo code for my imaginary class hierarchy:
class specialgrid( grid, pygridtablebase):
"""special grid that uses itself as the table and has methods for
extra renderers too"""
def specgetattr1():
def specgetattr2():
def specgetlabeldata():
...
def getcellattr():
...
And then here is a mixin class for implementing styles as CSS:
class CSSSpecialStyleMixIn(object):
"""overrides methods for all attributes, including table/cell
attributes and special renderers"""
def specgetattr1():
def specgetattr2():
def getcellattr():
And here is a mixin class that implements data access to header labels
AND grid cell data:
class Model1SpecialGridMixin():
"""overrides methods for all data, including table/cell values and
label values. uses a specific data model."""
def specgetlabeldata():
return data_from_model1
def getcellvalue():
return data_from_model1
etc.
If there cannot be a commin specialgrid class, then there cannot be
compact mixin classes - but I need them!
Thanks,
Laszlo