wxPyGridCellRenderer problems

I love wxPython, but although I'm able to make cell renderers that
work, I am having two problems with them.

First: SetDefaultRenderer doesn't seem to do anything. If I create a
new grid and then set the default renderer, I would expect all of the
cells to start using it, right? After all, I haven't overridden the
renderer for any cell yet. Does anyone know why this wouldn't work?

Note: I was able to work around this problem by setting the cell
renderer for every grid cell. However, this has led to the second
problem...

Second: If I delete a row after setting cell renderers, the
application crashes with a "Application Error: memory could not be
read".

I have tried to work around this problem by capturing the old
renderer with a GetCellRenderer and then resetting it back before
deleting the row, but it did not help.

I'm running this in WindowsXP, wxPython 2.4.1.2, Python 2.2.1.

Here's some bare-minimum source to demonstrate these two problems.
Please try it out and post a solution or work-around. Thanks!

crash.pyw:

···

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

class Renderer(wxPyGridCellRenderer):
    def Draw(self, Grid, Attr, DC, Rect, Row, Col, IsSelected):
        DC.SetPen(wxTRANSPARENT_PEN)
        DC.SetBrush(wxRED_BRUSH)
        DC.DrawRectangle(Rect.x, Rect.y, Rect.width, Rect.height)

class BoaApp(wxApp):
    def OnInit(self):
        self.main = wxFrame(id=100, name='', parent=None,
              pos=wxPoint(298, 185), size=wxSize(411, 226),
              style=wxDEFAULT_FRAME_STYLE, title='')
        self.button1 = wxButton(id=101, label='Kill Row',
              name='', parent=self.main, pos=wxPoint(312, 64),
              size=wxSize(75, 23), style=0)
        EVT_BUTTON(self.button1, 101, self.OnButton1Button)

        self.grid1 = wxGrid(id=102, name='', parent=self.main,
              pos=wxPoint(8, 8), size=wxSize(296, 184), style=0)
        self.grid1.CreateGrid(10, 3)
        R = Renderer()

        # QUESTION #1: SetDefaultRenderer should affect all cells,
        # but it doesn't. Why not?
        self.grid1.SetDefaultRenderer(R)
        # QUESTION #2: Setting the renderer for a cell in row 0
        # and a cell in row 1 works fine, but when you click the
        # button to delete row 0, it crashes with an app error. Why?
        self.grid1.SetCellRenderer(0, 0, R)
        self.grid1.SetCellRenderer(1, 0, R)

        self.main.Show()
        return True

    def OnButton1Button(self, event):
        self.grid1.DeleteRows()

application = BoaApp(0)
application.MainLoop()

Gre7g.

=================================================================
Gre7g Luterman gre7g@wolfhome.com http://www.templeofluna.com/
Stay informed: http://www.templeofluna.com/keeper/mailinglist.htm
                      Internet junkie: Turn on, log in, drop out.

Hi Greg,

Attached is a version with some lines marked with "wfb" which I think does the trick.

I was working on grid stuff and looking through that code noticed that a clone method is used in the demo, so initially just guessed that that caused your problem.

See you
Werner

Gre7g Luterman wrote:

rendererproblem.py (1.6 KB)

···

I love wxPython, but although I'm able to make cell renderers that work, I am having two problems with them.

First: SetDefaultRenderer doesn't seem to do anything. If I create a new grid and then set the default renderer, I would expect all of the cells to start using it, right? After all, I haven't overridden the renderer for any cell yet. Does anyone know why this wouldn't work?

Note: I was able to work around this problem by setting the cell renderer for every grid cell. However, this has led to the second problem...

Second: If I delete a row after setting cell renderers, the application crashes with a "Application Error: memory could not be read".

I have tried to work around this problem by capturing the old renderer with a GetCellRenderer and then resetting it back before deleting the row, but it did not help.

I'm running this in WindowsXP, wxPython 2.4.1.2, Python 2.2.1.

Here's some bare-minimum source to demonstrate these two problems. Please try it out and post a solution or work-around. Thanks!

crash.pyw:

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

class Renderer(wxPyGridCellRenderer):
   def Draw(self, Grid, Attr, DC, Rect, Row, Col, IsSelected):
       DC.SetPen(wxTRANSPARENT_PEN)
       DC.SetBrush(wxRED_BRUSH)
       DC.DrawRectangle(Rect.x, Rect.y, Rect.width, Rect.height)

class BoaApp(wxApp):
   def OnInit(self):
       self.main = wxFrame(id=100, name='', parent=None,
             pos=wxPoint(298, 185), size=wxSize(411, 226),
             style=wxDEFAULT_FRAME_STYLE, title='')
       self.button1 = wxButton(id=101, label='Kill Row',
             name='', parent=self.main, pos=wxPoint(312, 64),
             size=wxSize(75, 23), style=0)
       EVT_BUTTON(self.button1, 101, self.OnButton1Button)

       self.grid1 = wxGrid(id=102, name='', parent=self.main,
             pos=wxPoint(8, 8), size=wxSize(296, 184), style=0)
       self.grid1.CreateGrid(10, 3)
       R = Renderer()

       # QUESTION #1: SetDefaultRenderer should affect all cells,
       # but it doesn't. Why not?
       self.grid1.SetDefaultRenderer(R)
       # QUESTION #2: Setting the renderer for a cell in row 0
       # and a cell in row 1 works fine, but when you click the
       # button to delete row 0, it crashes with an app error. Why?
       self.grid1.SetCellRenderer(0, 0, R)
       self.grid1.SetCellRenderer(1, 0, R)

       self.main.Show()
       return True

   def OnButton1Button(self, event):
       self.grid1.DeleteRows()

application = BoaApp(0)
application.MainLoop()

Gre7g.

=================================================================
Gre7g Luterman gre7g@wolfhome.com http://www.templeofluna.com/
Stay informed: http://www.templeofluna.com/keeper/mailinglist.htm
                     Internet junkie: Turn on, log in, drop out.

---------------------------------------------------------------------
To unsubscribe, e-mail: wxPython-users-unsubscribe@lists.wxwindows.org
For additional commands, e-mail: wxPython-users-help@lists.wxwindows.org

Attached is a version with some lines marked with "wfb" which I think
does the trick.

I was working on grid stuff and looking through that code noticed that
a clone method is used in the demo, so initially just guessed that
that caused your problem.

Interesting! I'm not sure what the clone method is for, but it seems
to work with or without it now. I guess I just have to have a unique
instance of Renderer for each cell or something explodes on deletion.
Thanks tons and tons for finding that, Werner!

I'm still puzzled on the SetDefaultRenderer thing though. Does
anyone know why that doesn't work? Does anyone have any code where
it does work?

TIA,

Gre7g.

···

=================================================================
Gre7g Luterman gre7g@wolfhome.com http://www.templeofluna.com/
Stay informed: http://www.templeofluna.com/keeper/mailinglist.htm

         I want to be the master of time and space, a living god,
                            ...and then I'd like to visit Europe.

Gre7g Luterman wrote:

I'm still puzzled on the SetDefaultRenderer thing though. Does anyone know why that doesn't work? Does anyone have any code where it does work?

IIRC, a long time ago somebody broke that when adding some new feature and nobody knew quite how to fix it and keep both. Since then another rewrite of the wxGrid was started and so for most problems people are just waiting for that to happen. Please check SF to see if there is a bug about this already and if not then enter a bug report about it so it doens't get lost.

···

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

Greg,

Gre7g Luterman wrote:

Attached is a version with some lines marked with "wfb" which I think
does the trick.

I was working on grid stuff and looking through that code noticed that
a clone method is used in the demo, so initially just guessed that
that caused your problem.
   
Interesting! I'm not sure what the clone method is for, but it seems to work with or without it now. I guess I just have to have a unique instance of Renderer for each cell or something explodes on deletion. Thanks tons and tons for finding that, Werner!

Clone (I believe) ensures/allows you to have specific information per instance, e.g. in validators, which I use for db access, I pass a fieldname variable (and other stuff) which is unique for that instance. I guess as in your case you don't pass anything it doesn't matter.

···

I'm still puzzled on the SetDefaultRenderer thing though. Does anyone know why that doesn't work? Does anyone have any code where it does work?

TIA,

Gre7g.

=================================================================
Gre7g Luterman gre7g@wolfhome.com http://www.templeofluna.com/
Stay informed: http://www.templeofluna.com/keeper/mailinglist.htm

        I want to be the master of time and space, a living god,
                           ...and then I'd like to visit Europe.

---------------------------------------------------------------------
To unsubscribe, e-mail: wxPython-users-unsubscribe@lists.wxwindows.org
For additional commands, e-mail: wxPython-users-help@lists.wxwindows.org