Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to flag rows to be hidden in QAbstractItemModel-derived model

I'm implementing a Qt based tree view, where the view is a QTreeView-based class and the model is a QAbstractItemModel-based class. The tree is supposed to have millions of nodes in it. I'm implementing a filtering mechanism, in which filtered out nodes are just hidden in the tree view. (I don't want to use QSortFilterProxyModel)

The model's internal data structure looks somewhat like this.

class MyTreeItem
{
 ...
 private:
      QList<MyTreeItem *> _children;
      bool                _isHidden;
 };

 class MyTreeModel : public QAbstractItemModel 
 {
  ...
  private:
       MyTreeItem * _rootNode;
  };

I can determine whether a particular node (MyTreeItem*) should be filtered while the model data structure is being populated. So I want to let the QTreeView know that this item should be hidden while populating the data structure, rather than traversing the entire tree again and hiding rows after populating.

Honestly, I'm in the design stage, so I don't have any real code. My requirement is, while populating the data structure, I will determine whether the current node should be filtered, and if so, will set the flag _isHidden. But I'm not sure how to let the view know when to hide the row by calling QTreeView::setRowHidden() or by some other means.

Please share your thoughts on best way do this. Thanks.

like image 553
susiriss Avatar asked Dec 21 '17 06:12

susiriss


1 Answers

There is no built-in data flags to hide a cell (or row) in the standard Qt model item views. You can disable items or make the non-selectable, but not hide them entirely.

You could of course loop through your model and call QTreeView::setRowHidden() manually but you indicate you don't want to do that, and I would tend to agree (it would be much more efficient and practical to use a proxy model).

So you would most likely want to subclass one of the item views to get your desired effect and filter them there based on your custom flag. There is also the item delegate route (also set at the view level, not the model), so you might be able to filter out fields there by simply not painting them (but I've never tried that).

Or as suggested in the comments use QSortFilterProxyModel which is designed exactly for what you're asking (and really isn't going to add noticeable overhead to a typical GUI application on modern hardware). You could also write your own proxy model. You can use only the parts of QSortFilterProxyModel code which you need, for example.

Or as I also already suggested, simply don't include the rows you don't want when building the model.

like image 65
Maxim Paperno Avatar answered Sep 16 '22 21:09

Maxim Paperno