Results 1 to 2 of 2

Thread: Problem while deleting item in QTreeView

  1. #1
    Join Date
    Aug 2013
    Posts
    6
    Qt products
    Qt5
    Platforms
    Windows

    Default Problem while deleting item in QTreeView

    Hello,

    I have a QTreeView with some simple custom items in it.
    I also have a simple CustomTreeModel derived from QAbstractItemModel.

    I have a QMenu setup so I can click on the items in the tree and press "Delete" which is supposed to delete the current selected item and all its children.

    this is the code that I use to delete the items, it works but only for the children, If I call deleteLater() on the current selected item the app crashes.

    Qt Code:
    1. void MyCustomItem::OnDelete()
    2. {
    3. const QObjectList& childrenList = children();
    4. int numChildren = childrenList.size();
    5. for(unsigned int i = 0; i < numChildren; ++i)
    6. {
    7. QObject* pChildObj = childrenList[0];
    8. MyCustomItem* pChild = qobject_cast<MyCustomItem*>(pChildObj);
    9. if(pChild)
    10. {
    11. pChild->OnDelete();
    12. delete pChild;
    13. }
    14. }
    15.  
    16. QTreeView* pTV = mpAssociatedTreeView; //for simplicity assume that every object knows the treeview it is in
    17. pTV->clearSelection();
    18. pTV->reset();
    19.  
    20.  
    21. deleteLater(); <== if I comment out this line it doesn't crash and all the children objects in the tree are gone
    22. }
    To copy to clipboard, switch view to plain text mode 

    I have seen so many posts about using removeRows in the model rather than actually calling delete on the objects, but I fail to understand how these are exactly working.

    this is the crash callstack that I get when using deleteLater() on my currently selected item in the tree.

    Qt Code:
    1. > Qt5Cored.dll!QObject::parent() Line 386 C++
    2. MyApp.exe!CustomTreeModel::parent(const QModelIndex & index={...}) Line 109 C++
    3. Qt5Cored.dll!QModelIndex::parent() Line 462 C++
    4. Qt5Widgetsd.dll!QTreeView::drawRow(QPainter * painter=0x000000000018a9a8, const QStyleOptionViewItem & option={...}, const QModelIndex & index={...}) Line 1545 C++
    5. Qt5Widgetsd.dll!QTreeView::drawTree(QPainter * painter=0x000000000018a9a8, const QRegion & region={...}) Line 1456 C++
    6. Qt5Widgetsd.dll!QTreeView::paintEvent(QPaintEvent * event=0x000000000018bca0) Line 1282 C++
    7. Qt5Widgetsd.dll!QWidget::event(QEvent * event=0x000000000018bca0) Line 8030 C++
    8. Qt5Widgetsd.dll!QFrame::event(QEvent * e=0x000000000018bca0) Line 534 C++
    9. Qt5Widgetsd.dll!QAbstractScrollArea::viewportEvent(QEvent * e=0x000000000018bca0) Line 1163 C++
    10. Qt5Widgetsd.dll!QAbstractItemView::viewportEvent(QEvent * event=0x000000000018bca0) Line 1680 C++
    11. Qt5Widgetsd.dll!QTreeView::viewportEvent(QEvent * event=0x000000000018bca0) Line 1263 C++
    12. Qt5Widgetsd.dll!QAbstractScrollAreaPrivate::viewportEvent(QEvent * event=0x000000000018bca0) Line 105 C++
    13. Qt5Widgetsd.dll!QAbstractScrollAreaFilter::eventFilter(QObject * o=0x0000000008993450, QEvent * e=0x000000000018bca0) Line 121 C++
    14. Qt5Cored.dll!QCoreApplicationPrivate::sendThroughObjectEventFilters(QObject * receiver=0x0000000008993450, QEvent * event=0x000000000018bca0) Line 967 C++
    15. Qt5Widgetsd.dll!QApplicationPrivate::notify_helper(QObject * receiver=0x0000000008993450, QEvent * e=0x000000000018bca0) Line 3451 C++
    16. Qt5Widgetsd.dll!QApplication::notify(QObject * receiver=0x0000000008993450, QEvent * e=0x000000000018bca0) Line 3420 C++
    17. Qt5Cored.dll!QCoreApplication::notifyInternal(QObject * receiver=0x0000000008993450, QEvent * event=0x000000000018bca0) Line 871 C++
    18. Qt5Cored.dll!QCoreApplication::sendSpontaneousEvent(QObject * receiver=0x0000000008993450, QEvent * event=0x000000000018bca0) Line 235 C++
    19. Qt5Widgetsd.dll!QWidgetPrivate::drawWidget(QPaintDevice * pdev=0x0000000008949888, const QRegion & rgn={...}, const QPoint & offset={...}, int flags=4, QPainter * sharedPainter=0x0000000000000000, QWidgetBackingStore * backingStore=0x0000000008b1f1c0) Line 5133 C++
    20. Qt5Widgetsd.dll!QWidgetPrivate::paintSiblingsRecursive(QPaintDevice * pdev=0x0000000008949888, const QList<QObject *> & siblings={...}, int index=0, const QRegion & rgn={...}, const QPoint & offset={...}, int flags=4, QPainter * sharedPainter=0x0000000000000000, QWidgetBackingStore * backingStore=0x0000000008b1f1c0) Line 5325 C++
    21. Qt5Widgetsd.dll!QWidgetPrivate::paintSiblingsRecursive(QPaintDevice * pdev=0x0000000008949888, const QList<QObject *> & siblings={...}, int index=2, const QRegion & rgn={...}, const QPoint & offset={...}, int flags=4, QPainter * sharedPainter=0x0000000000000000, QWidgetBackingStore * backingStore=0x0000000008b1f1c0) Line 5312 C++
    22. Qt5Widgetsd.dll!QWidgetPrivate::drawWidget(QPaintDevice * pdev=0x0000000008949888, const QRegion & rgn={...}, const QPoint & offset={...}, int flags=4, QPainter * sharedPainter=0x0000000000000000, QWidgetBackingStore * backingStore=0x0000000008b1f1c0) Line 5183 C++
    23. Qt5Widgetsd.dll!QWidgetPrivate::paintSiblingsRecursive(QPaintDevice * pdev=0x0000000008949888, const QList<QObject *> & siblings={...}, int index=0, const QRegion & rgn={...}, const QPoint & offset={...}, int flags=4, QPainter * sharedPainter=0x0000000000000000, QWidgetBackingStore * backingStore=0x0000000008b1f1c0) Line 5325 C++
    24. Qt5Widgetsd.dll!QWidgetPrivate::drawWidget(QPaintDevice * pdev=0x0000000008949888, const QRegion & rgn={...}, const QPoint & offset={...}, int flags=4, QPainter * sharedPainter=0x0000000000000000, QWidgetBackingStore * backingStore=0x0000000008b1f1c0) Line 5183 C++
    25. Qt5Widgetsd.dll!QWidgetPrivate::paintSiblingsRecursive(QPaintDevice * pdev=0x0000000008949888, const QList<QObject *> & siblings={...}, int index=4, const QRegion & rgn={...}, const QPoint & offset={...}, int flags=4, QPainter * sharedPainter=0x0000000000000000, QWidgetBackingStore * backingStore=0x0000000008b1f1c0) Line 5325 C++
    26. Qt5Widgetsd.dll!QWidgetPrivate::drawWidget(QPaintDevice * pdev=0x0000000008949888, const QRegion & rgn={...}, const QPoint & offset={...}, int flags=4, QPainter * sharedPainter=0x0000000000000000, QWidgetBackingStore * backingStore=0x0000000008b1f1c0) Line 5183 C++
    27. Qt5Widgetsd.dll!QWidgetPrivate::paintSiblingsRecursive(QPaintDevice * pdev=0x0000000008949888, const QList<QObject *> & siblings={...}, int index=1, const QRegion & rgn={...}, const QPoint & offset={...}, int flags=4, QPainter * sharedPainter=0x0000000000000000, QWidgetBackingStore * backingStore=0x0000000008b1f1c0) Line 5325 C++
    28. Qt5Widgetsd.dll!QWidgetPrivate::drawWidget(QPaintDevice * pdev=0x0000000008949888, const QRegion & rgn={...}, const QPoint & offset={...}, int flags=4, QPainter * sharedPainter=0x0000000000000000, QWidgetBackingStore * backingStore=0x0000000008b1f1c0) Line 5183 C++
    29. Qt5Widgetsd.dll!QWidgetPrivate::paintSiblingsRecursive(QPaintDevice * pdev=0x0000000008949888, const QList<QObject *> & siblings={...}, int index=0, const QRegion & rgn={...}, const QPoint & offset={...}, int flags=4, QPainter * sharedPainter=0x0000000000000000, QWidgetBackingStore * backingStore=0x0000000008b1f1c0) Line 5325 C++
    30. Qt5Widgetsd.dll!QWidgetPrivate::drawWidget(QPaintDevice * pdev=0x0000000008949888, const QRegion & rgn={...}, const QPoint & offset={...}, int flags=4, QPainter * sharedPainter=0x0000000000000000, QWidgetBackingStore * backingStore=0x0000000008b1f1c0) Line 5183 C++
    31. Qt5Widgetsd.dll!QWidgetPrivate::paintSiblingsRecursive(QPaintDevice * pdev=0x0000000008949888, const QList<QObject *> & siblings={...}, int index=0, const QRegion & rgn={...}, const QPoint & offset={...}, int flags=4, QPainter * sharedPainter=0x0000000000000000, QWidgetBackingStore * backingStore=0x0000000008b1f1c0) Line 5325 C++
    32. Qt5Widgetsd.dll!QWidgetPrivate::drawWidget(QPaintDevice * pdev=0x0000000008949888, const QRegion & rgn={...}, const QPoint & offset={...}, int flags=4, QPainter * sharedPainter=0x0000000000000000, QWidgetBackingStore * backingStore=0x0000000008b1f1c0) Line 5183 C++
    33. Qt5Widgetsd.dll!QWidgetPrivate::paintSiblingsRecursive(QPaintDevice * pdev=0x0000000008949888, const QList<QObject *> & siblings={...}, int index=9, const QRegion & rgn={...}, const QPoint & offset={...}, int flags=4, QPainter * sharedPainter=0x0000000000000000, QWidgetBackingStore * backingStore=0x0000000008b1f1c0) Line 5325 C++
    34. Qt5Widgetsd.dll!QWidgetPrivate::drawWidget(QPaintDevice * pdev=0x0000000008949888, const QRegion & rgn={...}, const QPoint & offset={...}, int flags=5, QPainter * sharedPainter=0x0000000000000000, QWidgetBackingStore * backingStore=0x0000000008b1f1c0) Line 5183 C++
    35. Qt5Widgetsd.dll!QWidgetBackingStore::sync() Line 1093 C++
    To copy to clipboard, switch view to plain text mode 

    it looks to me as if the qtreeview is still drawing the items but I have just deleted one. In fact

    Qt Code:
    1. QModelIndex CustomTreeModel::parent(const QModelIndex &index) const
    2. {
    3. if( !index.isValid() )
    4. return QModelIndex();
    5.  
    6. QObject *indexObject = static_cast<QObject*>( index.internalPointer() );
    7. QObject *parentObject = indexObject->parent(); //the indexObject is garbage at this point
    8.  
    9. if( parentObject == m_root )
    10. return QModelIndex();
    11.  
    12. QObject *grandParentObject = parentObject->parent();
    13.  
    14. return createIndex( grandParentObject->children().indexOf( parentObject ), 0, parentObject );
    15. }
    To copy to clipboard, switch view to plain text mode 

    one more thing I can say is that from looking at my CustomTreeModel (where I store the root of my tree) I can tell that the root is the only object left after I delete its only child (with 1 subchild).

    this is the tree before calling pItemA->OnDelete()

    root (invisible)
    +--- ItemA
    +-------- ItemA0



    anyone has some suggestions ? I tried look at the Qt examples as well to understand how to create a clean QTreeView but its not very clear to me.

    any help is appreciated.
    Last edited by QtNewbieNeedsHelp; 4th September 2013 at 06:35.

  2. #2
    Join Date
    Mar 2011
    Location
    Hyderabad, India
    Posts
    1,882
    Thanks
    3
    Thanked 452 Times in 435 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows
    Wiki edits
    15

    Default Re: Problem while deleting item in QTreeView

    Use beginRemoveRows() and endRemoveRows() in the CustomTreeModel.
    example
    Qt Code:
    1. beginRemoveRows()
    2. //Here delete the item/items from internal contaner.
    3. endRemoveRows()
    4. //Now tree view will not access the deleted item.
    To copy to clipboard, switch view to plain text mode 
    When you know how to do it then you may do it wrong.
    When you don't know how to do it then it is not that you may do it wrong but you may not do it right.

Similar Threads

  1. Replies: 0
    Last Post: 1st May 2012, 23:11
  2. Removing item from layout without deleting it.
    By mrc_pl in forum Qt Programming
    Replies: 2
    Last Post: 24th January 2012, 11:24
  3. Problem with deleting items from QGraphicsScene
    By Wojtek_SZ in forum Qt Programming
    Replies: 7
    Last Post: 20th September 2011, 12:55
  4. Problem with Deleting QDomNode
    By metdos in forum Qt Programming
    Replies: 6
    Last Post: 16th July 2010, 18:58
  5. deleting first item in a list
    By soul_rebel in forum Qt Programming
    Replies: 2
    Last Post: 6th April 2006, 17:49

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.