How to prorer set wxGridCellRenderer for xGrid by SetColAttr()? Topic is solved

If you are using the main C++ distribution of wxWidgets, Feel free to ask any question related to wxWidgets development here. This means questions regarding to C++ and wxWidgets, not compile problems.
Post Reply
psion_revo
Earned a small fee
Earned a small fee
Posts: 12
Joined: Sun Feb 07, 2016 10:13 am

How to prorer set wxGridCellRenderer for xGrid by SetColAttr()?

Post by psion_revo »

Hi,
I will need to create own wxGridCellRenderers and wxGridCellEditors in my proj.
So, I try to understand how it should work.

First, I've found that I need to use IncRef() before SetColAttr().

Now,I have another error when I close an app:
"Assert GetEventHandler()==this failed in ~wxWindowBase: any pushed event handlers must have been removed".

In MyFrame::MyFrame I do:

Code: Select all

    
    dg = new wxGrid(pn1, ID_GRID4, wxPoint(56,48), wxSize(264,216), 0, _T("ID_GRID4"));
    dg->CreateGrid(4,0);
    dg->SetRowLabelSize(20);
    dg->SetColLabelSize(20);
    dg->DisableDragRowSize();
    dg->SetDefaultCellBackgroundColour(wxColour(128,128,128));
    dg->AppendCols(3);
    dg->SetColLabelValue(0,wxT("A"));
    dg->SetColLabelValue(1,wxT("B"));
    dg->SetColLabelValue(2,wxT("C"));
    wxGridCellAttr* pAttr = new wxGridCellAttr;
    pAttr->IncRef();
    pAttr->SetBackgroundColour(wxColour(25,255,255));
    wxGridCellAttr* pAttrBool = new wxGridCellAttr;
    pAttrBool->IncRef();
    pAttrBool->SetBackgroundColour(wxColour(200,155,255));
    pAttrBool->SetRenderer(new wxGridCellBoolRenderer());
    pAttrBool->SetEditor(new wxGridCellBoolEditor());
    pAttrBool->SetAlignment(wxALIGN_CENTRE,wxALIGN_CENTRE);
    dg->SetColAttr(0,pAttr);
    dg->SetColAttr(1,pAttr);
    dg->SetColAttr(2,pAttrBool);
If I delete strings with SetRenderer or SetEditor, all is ok.
If I don't touch cells with Editor, all is ok too.

I suppose, I should do something in MyFrame::~MyFrame?
Thanks.
User avatar
doublemax
Moderator
Moderator
Posts: 19160
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: How to prorer set wxGridCellRenderer for xGrid by SetColAttr()?

Post by doublemax »

Unfortunately the whole reference counting stuff inside wxGrid is virtually undocumented and i've never used it myself.

But as a wild guess:

Code: Select all

dg->SetColAttr(0,pAttr);
dg->SetColAttr(1,pAttr);
Try calling IncRef() once for each call of SetColAttr().
Use the source, Luke!
psion_revo
Earned a small fee
Earned a small fee
Posts: 12
Joined: Sun Feb 07, 2016 10:13 am

Re: How to prorer set wxGridCellRenderer for xGrid by SetColAttr()?

Post by psion_revo »

Thank you for right direction!

I've tried:

Code: Select all

wxGridCellAttr* pAttr = new wxGridCellAttr;
 pAttr->IncRef();
 pAttr->IncRef();
Problem still exists.

After your answer, I've started look for IncRef() and SetCellEditor
and have found very good explanation (don't know is it good to put it here?):
From vadim at wxwidgets.org Wed Mar 5 05:54:05 2014:
Ownership rules are indeed very simple for windows and most other objects
in wx, as they are simply owned by the library. With grid editors (&c),
it's more complicated because you need to be able to share them between
cells. Hence ref counting. When you create the editor, it has ref count of 1.
When you give it to the grid (via SetCellEditor()), it still takes
ownership of it in the sense that it will decrement the ref count, so
something like grid->SetCellEditor(x, y, new wxGridCellEditor(...));
works as expected. But if you call IncRef() on the editor, e.g. to be able
to share it between two cells, then you must either call SetCellEditor()
twice with the same editor or call DecRef() on it too.
A common pitfall (which i fell into myself a little while ago) are
methods like wxGrid::GetCellEditor() where the reference counter for
the editor is implicitly increased. So you have to call DecRef() on
the pointer yourself when you're done with it. It is documented
though.
So, the code from first post works good if we remove pAttrBool->IncRef().

If I'm not mistaken:
If we do SetColAttr( ,pAttr) N times, then we have to add pAttr->IncRef() (N-1) times.

Thanks again!
User avatar
doublemax
Moderator
Moderator
Posts: 19160
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: How to prorer set wxGridCellRenderer for xGrid by SetColAttr()?

Post by doublemax »

After your answer, I've started look for IncRef() and SetCellEditor
and have found very good explanation (don't know is it good to put it here?):
Thanks, this is indeed helpful.

BTW: Whenever you see a post from "vadim", you can take it for granted. He's "Mr. wxWidgets" and does about 90-95% of all maintenance work on it.
Use the source, Luke!
Post Reply