Setting clientdata in a wxGridCellEditor. 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
RichardW
Earned a small fee
Earned a small fee
Posts: 14
Joined: Fri Apr 25, 2014 4:45 am

Setting clientdata in a wxGridCellEditor.

Post by RichardW »

I've created a trivial 5x5 wxGrid. I prime its first column thusly:

Code: Select all

    int row;
    wxStringClientData* data;
    for (row=0;row<5;++row) {
        grid->SetCellValue(row,0,wxString::Format("row %d",row));
        data = new wxStringClientData(wxString::Format("%d",row));
        grid->GetCellEditor(row,0)->SetClientData(data);
    }
Under the grid, I've created a button. Its onClick event looks like this:

Code: Select all

    int row;
    wxStringClientData* data;
    for (row=0;row<5;++row) {
        data = (wxStringClientData*)(grid->GetCellEditor(row,0)->GetClientData());
        wxMessageBox(data->GetData());
    }
When I click the button, it reports "4" 5 times. It's almost like there's only one ClientData for the entire grid. What am I not understanding?

Also, apologies in advance if this was answered elsewhere. I'm using 3.0.2 on MinGW.

Thank you,
Richard
User avatar
doublemax
Moderator
Moderator
Posts: 19114
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Setting clientdata in a wxGridCellEditor.

Post by doublemax »

When I click the button, it reports "4" 5 times. It's almost like there's only one ClientData for the entire grid. What am I not understanding?
Unless you create and assign a new wxGridCellEditor, one wxGridCellEditor is used for all cells.

But storing any additional information that way seems like bad design anyway. What exactly are you trying to achieve?
Use the source, Luke!
RichardW
Earned a small fee
Earned a small fee
Posts: 14
Joined: Fri Apr 25, 2014 4:45 am

Re: Setting clientdata in a wxGridCellEditor.

Post by RichardW »

I am trying to mimic something similar to a Gantt chart in the grid. I have projects that run across multiple columns and I was trying to store their IDs as clientdata. The fields are not editable. Instead, when you click them, an edit screen opens to allow editing of multiple properties.

Here's an ugly screenshot:
ss.jpg
The fields under the project name display daily labour use.

Does that make sense?

Thank you for any advice you can give.
User avatar
doublemax
Moderator
Moderator
Posts: 19114
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Setting clientdata in a wxGridCellEditor.

Post by doublemax »

If you really want to store the information in the grid, you could use hidden columns or rows. But i would store the information in a separate container, a vector or hashset, whatever suits best.
Use the source, Luke!
RichardW
Earned a small fee
Earned a small fee
Posts: 14
Joined: Fri Apr 25, 2014 4:45 am

Re: Setting clientdata in a wxGridCellEditor.

Post by RichardW »

Indeed, a vector of {row,col,projectid} would work nicely. I may use that instead of what I did, shown below...

What I did instead, and I only mention it for completeness, is implement a very simple GridCellEditor:

Code: Select all

class TextEditor : public wxGridCellTextEditor {
    
    wxString cdata;

public:
    
    void SetData(wxString data) {
        cdata=data;
    }
    
    wxString GetData() {
        return cdata;
    }
};
Am I way off base here?

Thank you,
Richard
User avatar
doublemax
Moderator
Moderator
Posts: 19114
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Setting clientdata in a wxGridCellEditor.

Post by doublemax »

That looks ok. But you will have to create several instances of these and assign them to a cell/row/column.

Also beware of the reference counting for cell editors, renderers etc. E.g. the GetCellEditor() call from your first post will increase the internal reference counter for the editor. In many cases you have to manually call DecRef() on the pointer.
Use the source, Luke!
RichardW
Earned a small fee
Earned a small fee
Posts: 14
Joined: Fri Apr 25, 2014 4:45 am

Re: Setting clientdata in a wxGridCellEditor.

Post by RichardW »

the GetCellEditor() call from your first post will increase the internal reference counter for the editor
I see the IncRef() in wxGridCellAttr::GetEditor. I guess I don't understand why anything's getting incremented when you're just returning a pointer. There's no memory allocation. Why would refcount change? I've dug around in the docs and didn't find a reference to this so please point me in the right direction.

For SetCellEditor(), docs say, "The grid will take ownership of the pointer." I *assume* that means I don't have to do any clean up. It's getting set with a simple, "grid->SetCellEditor(row,col,new TextEditor());"

Now I'm concerned I've got a memory leak but I'm confused as to *why* I have a memory leak.

Thanks,
Richard
User avatar
doublemax
Moderator
Moderator
Posts: 19114
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Setting clientdata in a wxGridCellEditor.

Post by doublemax »

I've never used wxGrid and i honestly don't know.

But the documentation for wxGrid::GetCellEditor() says:
The caller must call DecRef() on the returned pointer.
http://docs.wxwidgets.org/trunk/classwx ... 44e1f75d28
Use the source, Luke!
RichardW
Earned a small fee
Earned a small fee
Posts: 14
Joined: Fri Apr 25, 2014 4:45 am

Re: Setting clientdata in a wxGridCellEditor.

Post by RichardW »

Well, I can't argue that. :)

Now, every time I call GetCellEditor(), it looks something like this:

Code: Select all

te=(TextEditor*)grid->GetCellEditor(row,col);
projectid=te->GetData();
te->DecRef();
Thank you for all your help!
Richard
User avatar
Asimov
Earned some good credits
Earned some good credits
Posts: 146
Joined: Tue Nov 17, 2020 6:43 pm

Re: Setting clientdata in a wxGridCellEditor.

Post by Asimov »

Thank you RichardW. Your code from the first post in this thread helped me out tremendously.
I load my wxGrid from a vector, but I wanted to add the option of re-ording my grid rows, but that would have meant re-ordering my vector too.
So now I have added the id to the wxGrid I can re-order my lines and keep the ID with the lines without worrying about the vector.
I will probably destroy the vector as soon as the grid is populated now.

Doh just realised I copied your code without reading properly, and now I am having the same problem as you LOL

PS. I changed to the hidden column in the end as I don't edit on cell level, thanks anyway
Post Reply