wxGrid or wxGridTableBase loading
wxGrid or wxGridTableBase loading
I am examing wxGrid to display a table of data. I am looking for a way to load the data to the wxGrid and build the wxGrid based on the data. That is I would put the data in an array[row num][col data] and then create wxGrid(array) similar to JTable in java http://java.sun.com/j2se/1.5.0/docs/api ... Table.html
I have also looked at wxGridTableBase where I would like to do the same thing so I could create wxGrid(wxGridTableBase(array)). Like DefaultTableModel in Java http://java.sun.com/j2se/1.5.0/docs/api ... Model.html
The closest thing I have found is this reference to using a sequence of sequences http://aspn.activestate.com/ASPN/Mail/M ... rd/2985548 albiet they are referring to Python there. That reference does not actually use the sequences?? but rather utilizes wxDBTable. wxDBTable skips the functionality I seek and ties the table directly to the DB.
Other references speak of using wxGridTableBase to load the data but I don't see how wxGridTableBase.SetCellValue is any more efficient than wxGrid.SetValue. I still have to count rows and columns (build functions to do so).
I am concluding that there is no DefaultTableModel equivilant rather wxGridTableBase is equivilant to Java's AbstractTableModel.
So my question is am I correct or have I missed something?
I have also looked at wxGridTableBase where I would like to do the same thing so I could create wxGrid(wxGridTableBase(array)). Like DefaultTableModel in Java http://java.sun.com/j2se/1.5.0/docs/api ... Model.html
The closest thing I have found is this reference to using a sequence of sequences http://aspn.activestate.com/ASPN/Mail/M ... rd/2985548 albiet they are referring to Python there. That reference does not actually use the sequences?? but rather utilizes wxDBTable. wxDBTable skips the functionality I seek and ties the table directly to the DB.
Other references speak of using wxGridTableBase to load the data but I don't see how wxGridTableBase.SetCellValue is any more efficient than wxGrid.SetValue. I still have to count rows and columns (build functions to do so).
I am concluding that there is no DefaultTableModel equivilant rather wxGridTableBase is equivilant to Java's AbstractTableModel.
So my question is am I correct or have I missed something?
thanks
Brad
Brad
First, C++ is not Java, and wxWidgets not Swing.
wxGrid is a bit of difficult, and its API isn't the userfriendliest.
Depending on what you are doing, I would write my own
wxGridTableBase class, and overwrite the virtual Methods.
Within this class you can do all the Datahandling and so on.
You might take a look at my DataGrid, which connects
a normal DataClass to a wxGrid:
http://forums.wxwidgets.org/viewtopic.php?t=5638
phlox
wxGrid is a bit of difficult, and its API isn't the userfriendliest.
Depending on what you are doing, I would write my own
wxGridTableBase class, and overwrite the virtual Methods.
Within this class you can do all the Datahandling and so on.
You might take a look at my DataGrid, which connects
a normal DataClass to a wxGrid:
http://forums.wxwidgets.org/viewtopic.php?t=5638
phlox
wxListCtrl/View is only on Windows native, and you get a problem,cpp wrote: Or, you might consider using wxListView instead, IMHO wxListView is a LOT frendlier, cleaner, and easier to use that wxGrid. (not to mention a lot les buggy). Plus it uses a lot less resources because its native (in Win32 at least).
if you like to edit the entries after the 1. Column.
wxGridTableBase is a pretty nice class, and easy to derive from.
Especially if you like to edit your entries, this is imho the better way.
phlox
Rebuilding Grid based on TableBase data
I have created a wxGrid based on a customized wxGridTableBase. Now if I modify the data in wxGridTableBase, That is just change a value but don't add any more data, I can view that updated data by calling wxGrid->ForceRefresh(). But all that does is reread the data for the existing cells. It does not rebuild the wxGrid based on the data.
To give further detail the data in my wxGridTableBase determines the number of rows in my wxGrid. If I add more data theoretically that would result in more rows. I add data to the wxGridTableBase not to the wxGrid. And that is what I want to do...add more data not just change the existing data.
What I need is a way to have the grid rebuilt based on the data in the wxGridTableBase. That is if wxGrid->SetTable(MyGridTableBase) was used to build the grid wxGrid->UpDateTable() is needed to go get the lastest data from the Table Base.
The only method I see for rebuilding the grid is wxGrid::ProcessTableMessage but that requires me to pass a message with details about the rows or columns changed. But in my case the grid doesn't know anything about those rows or columns because they are change in the Table Base.
What I am looking for is some insight into how this was envisioned to work or some direction if I am missing something.
To give further detail the data in my wxGridTableBase determines the number of rows in my wxGrid. If I add more data theoretically that would result in more rows. I add data to the wxGridTableBase not to the wxGrid. And that is what I want to do...add more data not just change the existing data.
What I need is a way to have the grid rebuilt based on the data in the wxGridTableBase. That is if wxGrid->SetTable(MyGridTableBase) was used to build the grid wxGrid->UpDateTable() is needed to go get the lastest data from the Table Base.
The only method I see for rebuilding the grid is wxGrid::ProcessTableMessage but that requires me to pass a message with details about the rows or columns changed. But in my case the grid doesn't know anything about those rows or columns because they are change in the Table Base.
What I am looking for is some insight into how this was envisioned to work or some direction if I am missing something.
thanks
Brad
Brad
thanks timg...
But appending rows or columns may not be what needs to be done. The model of appending or deleting rows assumes that the user or wxGrid itself is making the decision to add or removed data. I my situation that desicision is made be the data source of the table base.
Assume that I have some function (GetData) that returns to me my data in key value pairs where the key is some id and the value is some object from which I can pull the column data for each row. When I first build the table base (subclass wxGridTableBase) I call my function, sort my data, and place it in some hashmap. GetNumberCols is fixed, GetNumberRows is myHashMap.size(), and I write GetValue to parse the data from the value object for each key. I now have a wxGridTableBase object for wxGrid->SetTable.
After some period of time or after some event the source of the data, which I received by calling my GetData function, has changed the data. So I need to call GetData again and rebuild the wxGridTableBase. The source of the data could be some database, could be some server, could be some instrumentation, or whatever. The point is that wxGrid and wxGridTableBase don't know anything more than the fact that the data has changed. So they can't append or delete rows.
So after further research this morning I have found that it hinges on the takeOwnership argument of SetTable. Setting takeOwnership to true says wxGrid will now own the data. If this is done one would use the methods you speak of to modify data. The caller would wish to own the table base only if the caller where going to modify the base data, as opposed to just a value of the data. Setting takeOwnership to false says that wxGrid will not modify the data (ie add or delete rows) but rather will defer to the table base to manage the data.
If one calls SetTable with takeOwnership set to true then one cannot call SetTable again for the life of the wxGrid unless the whole table base is replaced. There is a check in wxGrid->CreateGrid, wxCheckMsg(...), that I assume will prevent one from calling CreateGrid more then once. A similar effort for SetTable may be necessary. A caller who does not set takeOwnership to true but who attempts to replace the table base with a new table base will find that the old table base is lost.
I believe additional insight can be achieved by studying wxDbTable and wxDbTableBase.
But appending rows or columns may not be what needs to be done. The model of appending or deleting rows assumes that the user or wxGrid itself is making the decision to add or removed data. I my situation that desicision is made be the data source of the table base.
Assume that I have some function (GetData) that returns to me my data in key value pairs where the key is some id and the value is some object from which I can pull the column data for each row. When I first build the table base (subclass wxGridTableBase) I call my function, sort my data, and place it in some hashmap. GetNumberCols is fixed, GetNumberRows is myHashMap.size(), and I write GetValue to parse the data from the value object for each key. I now have a wxGridTableBase object for wxGrid->SetTable.
After some period of time or after some event the source of the data, which I received by calling my GetData function, has changed the data. So I need to call GetData again and rebuild the wxGridTableBase. The source of the data could be some database, could be some server, could be some instrumentation, or whatever. The point is that wxGrid and wxGridTableBase don't know anything more than the fact that the data has changed. So they can't append or delete rows.
So after further research this morning I have found that it hinges on the takeOwnership argument of SetTable. Setting takeOwnership to true says wxGrid will now own the data. If this is done one would use the methods you speak of to modify data. The caller would wish to own the table base only if the caller where going to modify the base data, as opposed to just a value of the data. Setting takeOwnership to false says that wxGrid will not modify the data (ie add or delete rows) but rather will defer to the table base to manage the data.
If one calls SetTable with takeOwnership set to true then one cannot call SetTable again for the life of the wxGrid unless the whole table base is replaced. There is a check in wxGrid->CreateGrid, wxCheckMsg(...), that I assume will prevent one from calling CreateGrid more then once. A similar effort for SetTable may be necessary. A caller who does not set takeOwnership to true but who attempts to replace the table base with a new table base will find that the old table base is lost.
I believe additional insight can be achieved by studying wxDbTable and wxDbTableBase.
thanks
Brad
Brad
When you Add Rows or the Rows change by an event outside the wxGrid,
you need to send an event to wxGrid, saying how many rows where added / deleted.
phlox
you need to send an event to wxGrid, saying how many rows where added / deleted.
Code: Select all
wxGridTableMessage msg( this,wxGRIDTABLE_NOTIFY_ROWS_INSERTED,size-num,num );
GetView()->ProcessTableMessage( msg );
But that misses the purpose of a model for the grid. Niether the grid nor the grids creator knows that the data changed. Only the model knows. In addition the number of rows in the grid may change depending on the data in the model. Only the model can deterimine how many rows are needed.
And in order for wxGridTableBase to pass a message to wxGrid, wxGrid must be a member of wxGridTableBase which it is presently. And having the wxGrid object as a member of the wxGridTableBase breaks the whole reason to have a seperate class for the model. One might as well just put all the funtionality into wxGrid itelf.
Your method works for Grids that aren't model based but it can't work for model based methods because only the model knows if something changed. (Well it can work and it does because wxGrid is a member of wxGridTableBase but like I said that defeats the purpose of a model for the grid because it's circular.) (Circlular, is that the right term....wxGridTableBase is a member of wxGrid and wxGrid is a member of wxGridTableBase.)
And in order for wxGridTableBase to pass a message to wxGrid, wxGrid must be a member of wxGridTableBase which it is presently. And having the wxGrid object as a member of the wxGridTableBase breaks the whole reason to have a seperate class for the model. One might as well just put all the funtionality into wxGrid itelf.
Your method works for Grids that aren't model based but it can't work for model based methods because only the model knows if something changed. (Well it can work and it does because wxGrid is a member of wxGridTableBase but like I said that defeats the purpose of a model for the grid because it's circular.) (Circlular, is that the right term....wxGridTableBase is a member of wxGrid and wxGrid is a member of wxGridTableBase.)
thanks
Brad
Brad
but thats the only way...kbsimm wrote:But that misses the purpose of a model for the grid. Niether the grid nor the grids creator knows that the data changed. Only the model knows. In addition the number of rows in the grid may change depending on the data in the model. Only the model can deterimine how many rows are needed.
And in order for wxGridTableBase to pass a message to wxGrid, wxGrid must be a member of wxGridTableBase which it is presently. And having the wxGrid object as a member of the wxGridTableBase breaks the whole reason to have a seperate class for the model. One might as well just put all the funtionality into wxGrid itelf.
Your method works for Grids that aren't model based but it can't work for model based methods because only the model knows if something changed. (Well it can work and it does because wxGrid is a member of wxGridTableBase but like I said that defeats the purpose of a model for the grid because it's circular.) (Circlular, is that the right term....wxGridTableBase is a member of wxGrid and wxGrid is a member of wxGridTableBase.)
I know wxGrid isn't perfect, and of course, it should be enough that wxGridTableBase::GetNumberRows/Cols is overloaded, but it isn't.
phlox