PDA

View Full Version : QAbstractProxyModel tutorial? or advice?



liversedge
1st August 2010, 16:51
Hi,

I got all excited when I saw this: http://labs.trolltech.com/blogs/2008/03/25/advanced-example-of-modelview/ then found the source link is broken :-(

I have a QSqlTableModel which is being displayed in a QTreeView. It works nicely.

I want to allow the user to 'groupBy' a particular column, generally a text field.

So as a first stab I wrote a QAbstractProxyModel to just pass things straight thru. I got it largely working except the SQLTableModel implements canFetchMore which I had to muck about with in rowCount and then all my troubles began.

I could share code and get help that way, but before that -- is there a good tutorial anywhere that will help me? I am particularly interested in understanding how createIndex is supposed to work and why it doesn't accept a parent parameter, even tho QModelIndex needs one....

Anyway thanks for any pointers you can give me with this.

Cheers,
Mark

liversedge
1st August 2010, 18:38
Perhaps it would be better to share my code.

The following works ok for me. In my main application I create a QSQLTableModel, do a select() on it and then while it canFetchMore I fetchMore (shouldn't the view do this?).

Then I create my GroupByModel and setSourceModel to the QSQLTableModel before then adding a QSortFilterProxyModel and setting its source model to my GroupByModel and then, finally, setModel on my QTableView to the QSortFilterProxyModel.

Is this code "correct" as a pass-through proxy (i.e. it doesn't do anything at all at the moment, just reflects the source model).

I'm about to start modifying it to create a mapping from the sqlmodel and would like to be sure I'm not doing things incorrectly....

Any advice gratefully received....



// Proxy model ... transparent at the moment
class GroupByModel : public QAbstractProxyModel
{
Q_OBJECT

private:
bool *groupBy;

public:

GroupByModel(bool *groupBy, QObject *parent = NULL) : QAbstractProxyModel(parent), groupBy(groupBy) {
setParent(parent);
}
~GroupByModel() {}

// create a model index, don't bother with parent for now
// since -1,-1 has no parent and all others have a parent of -1.-1
QModelIndex index(int row, int column, const QModelIndex & = QModelIndex()) const {
return createIndex(row,column);
}

// parent is at -1, -1. All others have a parent of -1, -1
QModelIndex parent(const QModelIndex &index) const {
// we are at the top, return an invalid parent
if (index.column() == -1 && index.row() == -1) return QModelIndex();
else return createIndex(-1,-1);
}

QModelIndex mapToSource(const QModelIndex &proxyIndex) const {

// we use the same co-ords for now, so map to the same
return sourceModel()->index(proxyIndex.row(),proxyIndex.column());
}

// source model should be the same as ours
QModelIndex mapFromSource(const QModelIndex &sourceIndex) const {
return index(sourceIndex.row(), sourceIndex.column());
}

// same columns as source please
int columnCount(const QModelIndex &parent = QModelIndex()) const {
return sourceModel()->columnCount(sourceModel()->index(parent.row(), parent.column()));
}

int rowCount(const QModelIndex &parent = QModelIndex()) const {
if (parent.row() == -1 && parent.column() == -1) {
return sourceModel()->rowCount(sourceModel()->index(parent.row(), parent.column()));
} else
return 0;
}

// does this index have children?
bool hasChildren(const QModelIndex &index) const {
// if it is the root index (-1,-1) - it might have children
if (index.row() == -1 && index.column() == -1 && rowCount(createIndex(-1,-1)))
return true;
else
return false;
}

};

liversedge
1st August 2010, 18:55
http://www.slideshare.net/mariusbu/qt-item-views-in-depth

Is failry good.

liversedge
5th August 2010, 19:57
http://gitorious.org/qtgroupingproxy/qtgroupingproxy

For future reference, in case someone stumbles across this thread, the kde guys have created a grouping proxy, it is at the url above.