Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Get all selected items in a treeview
Forum Updated to NodeBB v4.3 + New Features

Get all selected items in a treeview

Scheduled Pinned Locked Moved General and Desktop
4 Posts 3 Posters 3.9k Views 3 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • H Offline
    H Offline
    haroldmaude
    wrote on last edited by haroldmaude
    #1

    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
    Item6

    When 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:Child1

    Instead, 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.

    1 Reply Last reply
    0
    • sahadumS Offline
      sahadumS Offline
      sahadum
      wrote on last edited by sahadum
      #2

      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
          }
      }
      
      1 Reply Last reply
      0
      • M Offline
        M Offline
        mcosta
        wrote on last edited by
        #3

        Child Item have valid parent, so you can use it row number

        if (idx.parent().isValid()) {
            qDebug() << parent.row() << ":" << idx:row();
        }
        

        Once your problem is solved don't forget to:

        • Mark the thread as SOLVED using the Topic Tool menu
        • Vote up the answer(s) that helped you to solve the issue

        You can embed images using (http://imgur.com/) or (http://postimage.org/)

        H 1 Reply Last reply
        0
        • M mcosta

          Child Item have valid parent, so you can use it row number

          if (idx.parent().isValid()) {
              qDebug() << parent.row() << ":" << idx:row();
          }
          
          H Offline
          H Offline
          haroldmaude
          wrote on last edited by haroldmaude
          #4

          @mcosta
          @sahadum

          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()==1

          This 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.

          1 Reply Last reply
          0

          • Login

          • Login or register to search.
          • First post
            Last post
          0
          • Categories
          • Recent
          • Tags
          • Popular
          • Users
          • Groups
          • Search
          • Get Qt Extensions
          • Unsolved