I have implemented a lazily populated treeview by subclassing QAbstractItemModel. The implementation looks something like:
https://gist.github.com/gnufied/db9c4d805e2bb24d8c23
(I am not pasting code inline, so as to mess with messaging)
It is basically a tree representation of hierarchical data stored in table. Now, I want users to be able to sort the rows based on columns. Where columns are, "count" or "reference count". These values are basically integers.
The implementation on its own works, until I throw in QSortFilterProxyModel and I start to get lots of empty rows in the view. The hard problem is, this tends to happen only when I have lots of rows (like thousands or so).
The code for implementing sorting proxy is:
rootItem = RBKit::SqlConnectionPool::getInstance()->rootOfSnapshot(snapShotVersion);
model = new RBKit::HeapDataModel(rootItem, this);
proxyModel = new SortObjectProxyModel(this);
proxyModel->setSourceModel(model);
ui->treeView->setModel(proxyModel);
ui->treeView->setSortingEnabled(true);
I have subclassed QSortFilterProxyModel class and subclass implementation is really simple:
https://gist.github.com/gnufied/115f1a4fae3538534511
The documentation does say -
"This simple proxying mechanism may need to be overridden for source models with more complex behavior; for example, if the source model provides a custom hasChildren() implementation, you should also provide one in the proxy model."
But beyond that, I am not sure - what I am missing.
Thank you for responding. At this point I really don't care about resorting rows that were lazy loaded (when a node was expanded), so I went ahead and disabled sortingEnabled
and disabled dynamicSortFilter
too.
The new code looks like:
rootItem = RBKit::SqlConnectionPool::getInstance()->rootOfSnapshot(snapShotVersion);
model = new RBKit::HeapDataModel(rootItem, this);
proxyModel = new SortObjectProxyModel(this);
proxyModel->setSourceModel(model);
proxyModel->sort(2, Qt::DescendingOrder);
proxyModel->setDynamicSortFilter(false);
ui->treeView->setModel(proxyModel);
That still leaves with empty rows though.
In my oppinion You don't need to subclass QSortFilterProxyModel
for sorting on the top layer. If sortingEnabled == true
for your view then the view will perform sorting on the proxy model, which is not desirable as the model should sort itself. What you need is to to call proxyModel->sort(desiredColumn)
and that will display your model
sorted in the view without altering your data. By default the QSortFilterProxyModel
has its dynamicSortFilter
property on, which will cause the proxy model to automatically re-sort when data changes or row is inserted or removed. I didn't see emitting dataChanged signal anywhere in your HeapDataModel
, so maybe that could be a hint for you to get dynamically sorted rows. If you need to sort subitems then it goes little more complicated and then maybe you'll need to subclasss QSortFilterProxyModel
. These model-view abstractions are hard to learn but once you get it you can do miracles rapidly.
rootItem = RBKit::SqlConnectionPool::getInstance()->rootOfSnapshot(snapShotVersion);
model = new RBKit::HeapDataModel(rootItem, this);
proxyModel = new SortObjectProxyModel(this);
proxyModel->setSourceModel(model);
proxyModel->sort(column);
ui->treeView->setModel(proxyModel);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With