Get all selected items in a treeview
-
Hello,
I'm using QTreeView : tree, an AbstractItemModel : model, and a SelectionModel : selection.
==================
My tree is as follows:Item1
Item2
Item3
--Child1
--Child2
Item4
--Child1
Item5
Item6When I select, for instance, Item5, my selection model is updated.
I then ask it for selectedRows(). I am given the appropriate corresponding row number.When I select a child node, however, I am given the row number inside the node, such as Item4's Child1 returns a row number of 0..... but so does Item1
So if I select Item1 and Child1 of Item4, both row numbers are 0.
This results in Child1 and Item1 being iterated over back to back as below
================
Ex. I select Item1, Item 2, and Item 4's Child 1.I then use
foreach(const QModelIndex &id, selection->selectedRows())
{
//copy the row's contents to my clibpoard.
}My hope is it displays:
Item1
Item2
Item4:Child1Instead, I get
Child1
Item1
Item2======
Is there a way to get the desired output instead? My "foreach" seems to go "row 0, row 0, row 0, row 1, row 1, row 2, row 3, row 4, row 5"
where row 0 is each of the child nodes first, then the actual row 0
instead of iterating over them as they are displayed.
-
Hi,
to distinguish between parent items and child items you could set a user role at every item of the model.
create a user role:
enum ITEM_ROLES { MY_ITEM_LEVEL = Qt::UserRole }
create values for this role
enum ITEM_LEVELS { ITEM_LEVEL_PARENT = 0, ITEM_LEVEL_CHILD }
then set this role to the items
item->setData( MY_ITEM_LEVEL, ITEM_LEVEL_PARENT ) ;
and then check
QModelIndexList idxSelectedItems = ui->treeView->selectionModel()->selectedRows(); for ( auto iter = idxSelectedItems .constBegin(); iter != idxSelectedItems .constEnd(); ++iter ) { if ( iter->data( MY_ITEM_LEVEL ) == ITEM_LEVEL_PARENT ) { // handle parent } else if ( iter->data( MY_ITEM_LEVEL ) == ITEM_LEVEL_CHILD ) { // get parent of child item // handle child } }
-
Child Item have valid parent, so you can use it row number
if (idx.parent().isValid()) { qDebug() << parent.row() << ":" << idx:row(); }
-
Thank you for your responses! Both of these are great points. I have a similar implementation to Sahadum's suggestion in place regarding item roles, and Mcosta, that's the EXACT thing I was doing to determine if it's a child node.
The only problem is, when I query my selectionModel->selectedRows(), my rows still are out of order. When I run my foreach loop, this is what's given to me:
rows - 0, 0, 0, 1, 1, 1, 2, 3, 4, 5
deconstructed as below:item3:child1.row() ==0,
item4:child1.row() == 0,
item1.row()==0,item3:child2.row()==1
item4:child2.row()==1
item2.row()==1This is the order that the rows are presented to me in the foreach loop. I tried ignoring child nodes, and then adding their data to my QStringList when I encounter a parent. This orders things properly, but what if I select ONLY a child line, for instance Item3:Child1 - this will be ignored and not be copyable. I must then copy the parent and get ALL the children.
I still need a means of walking through my selectionModel that will give me the rows in the order they appear in my Treeview.