Hide or unhide a section in QTreeView/Model
-
Hi,
I have a QTreeView where a list of sections are shown based on the data I receive.
For exampleFruits -
............Apple
............Orange
Animals -
.............Lion
.............Tiger
Colors -
............Red
............Green
............BLue"-" = Arrow for hiding or unhiding the childrens
The Data is read from a model (inherited from QAbstractItemModel).
Currently While initializing the application all the Parent items ( Fruits, Animals & colors) are added to the model (root).Query:
There is a possibility that sometimes I may not receive a "section" of data. For example, the entire section of Animals is not received.
In that case I would like to Hide or remove the animal section and the result should be likeFruits -
............Apple
............Orange
Colors -
............Red
............Green
............BLueI have tried one possiblity that whenever I don't receive a particular section of the data, i "remove" that particular parent item from the root before adding child items.
Ex: root->removeItemAt(indexOfAnimal).So, basically I am adding or removing the section during runtime by updating the model itself.
Is it a good idea? Does it conform with MVC ?Is there a better way to do this?
Can we just hide or unhide the sections based on some condition using treeView itself?Section = parent + child items of a particular category.
-
Hi,
QSortFilterProxyModel might be your friend.
You can use it to filter out the empty top level items.
-
Hi @SGaist ,
Thank you for the hint.
I started experimenting with the QSortFilterProxyModel.
Below is the code snippet that I tried out.bool FilterModel::filterAcceptsRow(int source_row, const QModelIndex& source_parent) const { // check the current item bool result = false; QModelIndex currntIndex = sourceModel()->index(source_row, 0, source_parent); if (sourceModel()->hasChildren(currntIndex)) { result = true; } return result; }
I want to just check if a "first level" parent has a children or not.
But filterAcceptsRow( .. ) is recursilvely called for all the childrens.I want to filter/check only the first level parent because my tree view will never have second level childrens.
It's just a single parent and single child kind of thing.Example:
Color
........Red
........Green
Animal
........Tiger
........LionThere is no possibility for any child ex. "Red", to have further childrens. It is more like a table.
So, because of this I would like to apply filter only to the "parent" item (Color or Animal).
if parent haschildren, accept parent all the childrens else do not accept anything.Any idea how to do that?
-
Hi,
I tried out kind of a hack to do this.bool FilterModel::filterAcceptsRow(int source_row, const QModelIndex& source_parent) const { bool result = false; if (source_parent.row() != -1 || source_parent.column() != -1) { result = true; return result; } // check the current item bool result = false; QModelIndex currntIndex = sourceModel()->index(source_row, 0, source_parent); if (sourceModel()->hasChildren(currntIndex)) { result = true; } return result; }
Root seems to have row and column as -1 always.
So, if the row or column is -1, only then the rows (parents) are filtered.
Else (non-root parent), all are considered.Works as expected.
Is this fine? Or is there a better or an even standard solution for this ? -
The parent being invalid means that you have a top level item.
-
Hello,
Thanks a lot for the replies.
I found out another way by which we can hide the 'section' if the parent doesn't have any childrens.
ui.treeView->setRowHidden(parentRow, rootIndex, true)In my example,
Fruits -
............Apple
............Orange
Animals -
.............Lion
.............Tiger
Colors -
............Red
............Green
............BLueFruits is 0th parent
Animals is 1st parent
Colors is the 2nd parentSo whenever any of the children's are missing ( which we come to know while filling up the model ), I am setting the respective "parent" row as hidden.
This approach worked fine and as expected.Is anything wrong with this approach?
Model remains the same, only the view is hidden or unhidden based on some condition.
Please Let me know.