Results 1 to 3 of 3

Thread: How to move table view tree item along with its children with custom data.

  1. #1
    Join Date
    Aug 2019
    Posts
    2
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Windows

    Default How to move table view tree item along with its children with custom data.

    This is the header file for my tree item


    Qt Code:
    1. class TreeItem
    2. {
    3. public:
    4. explicit TreeItem( Container *data , TreeItem *parent = 0 );
    5. ~TreeItem();
    6. TreeItem *parent();
    7. void appendChild(TreeItem *child);
    8.  
    9. TreeItem *child(int iNumber);
    10. int childCount() const;
    11. int childNumber() const;
    12. Container data() const ;
    13. Container* GetContainer();
    14. bool setData(Container* data , QVariant value);
    15. void setContainer( Container* data);
    16. bool insertChildren(int position, int count );
    17. bool removeChildren( int position , int count );
    18. void removeChild(int row);
    19. void removeChild(TreeItem* itm);
    20. std::string getChildName(int row);
    21. std::string getName();
    22. int row() const;
    23. void insertChild(int pos, TreeItem *child);
    24.  
    25. private:
    26. QList<TreeItem*> childItems;
    27. Container* itemData;
    28. TreeItem* parentItem;
    29. };
    To copy to clipboard, switch view to plain text mode 
    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    Each tree item holds a pointer reference to a container object.

    when i move or copy( Cntrl Pressed) a single tree item i create a new instance of tree item and copy the data from the old item.

    Currently in my code i am able to do this for single item , how to do it for a item having multiple children.

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////



    Qt Code:
    1. bool dropMimeData(const QMimeData *mimeData, Qt::DropAction action, int row, int column, const QModelIndex &parent)
    2. {
    3. if (!mimeData->hasFormat(s_treeNodeMimeType)) {
    4. return false;
    5. }
    6. QByteArray data = mimeData->data(s_treeNodeMimeType);
    7. QDataStream stream(&data, QIODevice::ReadOnly);
    8. qint64 senderPid;
    9. stream >> senderPid;
    10. if (senderPid != QCoreApplication::applicationPid()) {
    11. return false;
    12. }
    13. TreeItem *parentNode = getItem(parent);
    14. int count;
    15. stream >> count;
    16. if (row == -1) {
    17. if (parent.isValid())
    18. row = 0;
    19. else
    20. row = rowCount(parent);
    21. }
    22. TreeItem *node;
    23. for (int i = 0; i < count; ++i) {
    24. qlonglong nodePtr;
    25. stream >> nodePtr;
    26. node = reinterpret_cast<TreeItem *>(nodePtr);
    27. if (node->row() < row && parentNode == node->parent())
    28. --row;
    29.  
    30. TreeItem *nodeNew = new TreeItem(node->GetContainer(), parentNode); // Create a new Data item using the node container's data.
    31. beginInsertRows(parent, row, row);
    32. parentNode->insertChild(row, nodeNew);
    33. endInsertRows();
    34. ++row;
    35.  
    36. }
    37.  
    38. if (QGuiApplication::keyboardModifiers() != Qt::ControlModifier)
    39. {
    40. removeItem(node);
    41. }
    42. return true;
    43. }
    To copy to clipboard, switch view to plain text mode 
    Last edited by sumit kang; 14th August 2019 at 12:24.

  2. #2
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    4,118
    Thanks
    235
    Thanked 656 Times in 646 Posts
    Qt products
    Qt5
    Platforms
    Windows Android

    Default Re: How to move table view tree item along with its children with custom data.

    Currently in my code i am able to do this for single item , how to do it for a item having multiple children.
    If children can have children can have children ..., then you'll need to design a pair of recursive methods to 1) create the tree inside the mime data object from the source item and 2) restore the tree from the mime data after the drop.

    For the first, you basically start at the source item and write its information to the stream, then recurse for each child, appending the child's information and then recursing into its children and appending their information, and so on until you reach bottom. You then recurse back up one level and handle the next child at that level until finally you have recursed back to the source item again. Your then have a mime data object that contains the tree and all of its sub-trees, rooted at the source item. For the recursive function, at a minimum you will need to pass in a pointer to the current tree item (source or child) as well as the data stream reference so you can append to it.

    Qt Code:
    1. // This recursive method is called from the method that creates the mime data at the beginning of the drag. It is called with the
    2. // source TreeItem and the writable QDataStream as arguments
    3. void buildTree( TreeItem * pItem, QDataStream & ds )
    4. {
    5. // write info for current item to data stream
    6. // ...
    7.  
    8. // Now do the same for each child of the current item. If no children, then the recursion stops going deeper here
    9. for each childItem in pItem->children()
    10. buildTree( childItem, ds );
    11.  
    12. // done at this level. Return and go up a level
    13. }
    To copy to clipboard, switch view to plain text mode 

    To restore, you do the same thing - from the data stream, restore the source item, then recurse to restore the first child's tree, and so forth until you have rebuilt the copy of the tree from the data stream. Once again, your recursive function will have to pass the data stream reference and probably the current parent item for the children you are reading in.

    Qt Code:
    1. // This method is initially called from the dropMimeData method after the data stream is opened.
    2. // When the recursion finally returns to the dropMimeData method, the TreeItem pointer that is returned
    3. // will contain the complete tree that was encoded in the mime data. It can then be inserted into
    4. // the proper place in the tree where it was dropped.
    5. TreeItem * restoreTree( QDataStream & ds )
    6. {
    7. TreeItem * thisItem = new TreeItem;
    8.  
    9. // restore thisItem's info from the stream, including the count of its children
    10. // ...
    11.  
    12. // then for each child, restore its sub-tree
    13. for ( auto nChild = 0; nChild < childCount; ++nChild )
    14. {
    15. TreeItem * pChild = restoreTree( ds );
    16. if ( pChild != nullptr )
    17. thisItem->appendChild( pChild );
    18. }
    19. return thisItem;
    20. }
    To copy to clipboard, switch view to plain text mode 

    You will probably have to add some bookkeeping information to the data stream when you create it so you can rebuild the tree structure. For example, for each tree item, you might write out the count of its children so you know if you have to recurse or not. You might also want to assign an ID to each node of the tree and write that out along with the ID of that node's parent, if any. That way you have a sanity check you can use to determine if you are rebuilding the tree correctly.

    Google "depth first tree traversal", "depth first search", or "depth first recursion" if you want to learn more.
    Last edited by d_stranz; 14th August 2019 at 21:26.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  3. #3
    Join Date
    Aug 2019
    Posts
    2
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Windows

    Default Re: How to move table view tree item along with its children with custom data.

    Quote Originally Posted by d_stranz View Post
    If children can have children can have children ..., then you'll need to design a pair of recursive methods to 1) create the tree inside the mime data object from the source item and 2) restore the tree from the mime data after the drop.

    For the first, you basically start at the source item and write its information to the stream, then recurse for each child, appending the child's information and then recursing into its children and appending their information, and so on until you reach bottom. You then recurse back up one level and handle the next child at that level until finally you have recursed back to the source item again. Your then have a mime data object that contains the tree and all of its sub-trees, rooted at the source item. For the recursive function, at a minimum you will need to pass in a pointer to the current tree item (source or child) as well as the data stream reference so you can append to it.

    Qt Code:
    1. // This recursive method is called from the method that creates the mime data at the beginning of the drag. It is called with the
    2. // source TreeItem and the writable QDataStream as arguments
    3. void buildTree( TreeItem * pItem, QDataStream & ds )
    4. {
    5. // write info for current item to data stream
    6. // ...
    7.  
    8. // Now do the same for each child of the current item. If no children, then the recursion stops going deeper here
    9. for each childItem in pItem->children()
    10. buildTree( childItem, ds );
    11.  
    12. // done at this level. Return and go up a level
    13. }
    To copy to clipboard, switch view to plain text mode 

    To restore, you do the same thing - from the data stream, restore the source item, then recurse to restore the first child's tree, and so forth until you have rebuilt the copy of the tree from the data stream. Once again, your recursive function will have to pass the data stream reference and probably the current parent item for the children you are reading in.

    Qt Code:
    1. // This method is initially called from the dropMimeData method after the data stream is opened.
    2. // When the recursion finally returns to the dropMimeData method, the TreeItem pointer that is returned
    3. // will contain the complete tree that was encoded in the mime data. It can then be inserted into
    4. // the proper place in the tree where it was dropped.
    5. TreeItem * restoreTree( QDataStream & ds )
    6. {
    7. TreeItem * thisItem = new TreeItem;
    8.  
    9. // restore thisItem's info from the stream, including the count of its children
    10. // ...
    11.  
    12. // then for each child, restore its sub-tree
    13. for ( auto nChild = 0; nChild < childCount; ++nChild )
    14. {
    15. TreeItem * pChild = restoreTree( ds );
    16. if ( pChild != nullptr )
    17. thisItem->appendChild( pChild );
    18. }
    19. return thisItem;
    20. }
    To copy to clipboard, switch view to plain text mode 

    You will probably have to add some bookkeeping information to the data stream when you create it so you can rebuild the tree structure. For example, for each tree item, you might write out the count of its children so you know if you have to recurse or not. You might also want to assign an ID to each node of the tree and write that out along with the ID of that node's parent, if any. That way you have a sanity check you can use to determine if you are rebuilding the tree correctly.

    Google "depth first tree traversal", "depth first search", or "depth first recursion" if you want to learn more.
    Thank you very much for the help.

Similar Threads

  1. Replies: 1
    Last Post: 31st March 2016, 10:51
  2. Replies: 3
    Last Post: 17th January 2016, 18:06
  3. Building Tree view from Table view which is already build.
    By DURGAPRASAD NEELAM in forum Newbie
    Replies: 6
    Last Post: 18th May 2015, 07:18
  4. Get data from table view after item was edited?
    By schmimona in forum Qt Programming
    Replies: 7
    Last Post: 8th September 2011, 12:47
  5. Help on adding children to tree view
    By vieraci in forum Qt Programming
    Replies: 3
    Last Post: 5th June 2009, 07:54

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.