PDA

View Full Version : A Totalling Proxy Model?



ChrisW67
6th April 2010, 03:48
Hi All,

I'm looking for a nudge in the right direction here.

I have a base QSqlTableModel containing up to 10000 rows of ~30 columns. 15 of those columns are numeric. The model is generally viewed through a QSortFilterProxyModel with a complex QSortFilterProxyModel::filterAcceptsRow() reimplementation to reduce the data set based on user options. This much works well.

I'd like to have an elegant way to get a total for each of the numeric columns. I could go directly to the database tables with a query but they do not reflect the current state of data in the model (i.e. add/edit/delete are handled in memory and not immediately followed by submitAll()).

I've pondered how to get an item model based solution that returns a single row of column totals and can be layered on top of the filter proxy (or base table). It's easy enough to iterate over the model row and columns and build a total when all the rows are there (in setModel()). However, making sure that the totals are updated efficiently is proving difficult. I can catch the


void rowsAboutToBeRemoved ( const QModelIndex & parent, int start, int end );
void rowsInserted ( const QModelIndex & parent, int start, int end );

signals and adjust total accordingly by subtracting or adding column values respectively. Catching:


void dataChanged ( const QModelIndex & topLeft, const QModelIndex & bottomRight );

does not let me see the previous value of the cells affected, so I cannot subtract them from the total before adding the new values. At the moment, any dataChanged() signal needs to completely recalculate the totals in affected columns.

Can anyone suggest a good/efficient/expedient way to achieve this? Should I just go brute force and recalculate all the totals on any change? Am I missing the blindingly obvious QTotalsProxyModel ;) ?

Thanks,
Chris W

norobro
7th April 2010, 01:07
I don't know of a QTotalsProxyModel;) but have you considered using a custom delegate? If you reimplement QItemDelegate::setModelData(), the new value will be in the editor. You can retrieve the current value from the model with model->data(), calculate the difference, adjust your totals and then call model->setData().

ChrisW67
7th April 2010, 04:06
Must admit I hadn't thought of that. I'd have to look at the ramifications of making the delegate dependent on a second model though.