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. Why does removeItem() + delete cause QGraphicsView to crush whereas delete doesn't?
Forum Updated to NodeBB v4.3 + New Features

Why does removeItem() + delete cause QGraphicsView to crush whereas delete doesn't?

Scheduled Pinned Locked Moved General and Desktop
6 Posts 3 Posters 2.9k Views 1 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.
  • D Offline
    D Offline
    dm.zhdanov
    wrote on last edited by
    #1

    I am creating the custom scene for QGraphicsView with items derived from QGraphicsViewGroup:
    @class QI_DiagramInteraction: public QGraphicsItemGroup
    {
    public:
    ...
    std::weak_ptr<QI_ObjectSchemaElement> params;
    ...
    }@

    Here QI_ObjectSchemaElement is custom shared data model element which defines the appearance and position of the item. Presently, the group is empty (I will add some QGraphicsRectItem elements into it in the future). The item functionality is realized by reimplementing the following QGraphicsViewGroup methods:
    @boundingRect ();
    shape();
    paint();
    @

    All three methods load the necessary data exclusively from the associated params object. When the data in params object are altered I force the updating of the scene by calling:
    @removeItem(it2->second);
    it2->second->show(); //I added this line because some of the items may be hidden at the removal time
    addItem(it2->second);@

    Everything works fine until I try to remove the items. I have read in the documentation that the preferable way to do it is to call removeItem() and then call delete (I also want to do it in two steps to reuse some of the items). I have no problems if the underlying params object did not change during the lifetime of QI_DiagramInteraction item. However, if some changes did take place I get the access violation error (but not immediately after deleteon) at the line 235 of qcoreapplication.h:
    @inline bool QCoreApplication::sendSpontaneousEvent(QObject *receiver, QEvent *event)
    {
    if (event) event->spont = true; return self ? self->notifyInternal(receiver, event) : false; // ERROR HERE!
    }@
    This indicates that the program tries to access the item instance after it had been deleted. Indeed, no error observed when I keep all the once created items.

    At first glance, the reason might be in wrong usage of signal-slot mechanism, so that some queued signal calls the deleted object. To check this guess I tried to collect the removed items into std::stack<QI_ObjectSchemaElement*> and delete them after reasonable delay but found that the same error still persists. Most surprisingly, everything started to work flawless when I changed the code to remove items by direct call of delete everywhere instead of invoking the removeItem() function. It seems that error after calling the removeItem occurs when QGraphicsView needs to repaint the region where the deleted item was located before changing the params pointer (even if it was actually correctly redrawn in the new position many times before actual removing and deletion). I also checked that no errors are generated in overwritten functions listed above.

    Can you, please, help me understand this error and the way to avoid it?

    1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi and welcome to devnet,

      Can you setup a minimal compilable example that shows this behavior ?

      Also, what Qt/OS combo are you using ?

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      0
      • D Offline
        D Offline
        dm.zhdanov
        wrote on last edited by
        #3

        I am using Qt 5.2.0 (Windows 8, Microsoft Visual C++ compiler 11.00 (x86)). I will try to setup the minimal example.

        1 Reply Last reply
        0
        • P Offline
          P Offline
          Pavel
          wrote on last edited by
          #4

          Hi!
          I have a similar problem. I create a QGraphicsItemGroup and push QGraphicItem's. Some time later I try to rebuild that group: first thing I do is delete previous. It looks like this:
          @
          void MapScene::RebuildGrid()
          {
          removeItem(m_pGrid); // <--- here is the problem
          delete m_pGrid;

          qreal fScale = m_pBackgoundItem->scale();
          qreal w = m_pBackgoundItem->boundingRect().right()*fScale;
          qreal h = m_pBackgoundItem->boundingRect().bottom()*fScale;
          m_pGrid = new QGraphicsItemGroup;
          for (int i = 0; i<w; i+=m_iCellGridSize)
          {
              QLine vline(i, 0, i, h);
              QGraphicsLineItem* pvGLI = new QGraphicsLineItem(vline);
              pvGLI->setZValue(2.0);
              m_pGrid->addToGroup(pvGLI);
          
              for (int j = 0; j<h; j+=m_iCellGridSize)
              {
                  QLine hline(0, j, w, j);
                  QGraphicsLineItem* phGLI = new QGraphicsLineItem(hline);
                  phGLI->setZValue(2.0);
                  m_pGrid->addToGroup(phGLI);
              }
          }
          
          addItem(m_pGrid);
          

          }
          @

          So removeItem is crashing. I tried to remove this line, however it's crashing after delete too. What could be wrong ?
          Thank you.

          1 Reply Last reply
          0
          • P Offline
            P Offline
            Pavel
            wrote on last edited by
            #5

            I found a problem.. I did clear the scene and then tried to delete an Item from the already cleared scene. So I think you should add some kind of comparison if the item exists before deleting and if it isn't show some kind of warning.

            1 Reply Last reply
            0
            • D Offline
              D Offline
              dm.zhdanov
              wrote on last edited by
              #6

              Pavel, I always make the checks you have suggested, so the my problem is caused by something else. I still did not figure out its reason. I found that usually it is NOT caused by items which are actually have been removed and deleted. However, recently I fixed bug in constructors of few of my graphicsItem objects (also not ones which I am actually removing and deleting) derived from multiple classes: i did not call the proper constructor for one of the base classes. I did not check, however, if this fixed the removeItem() issue. As an ad-hoc solution, I avoid using removeItem() in the code, and everything works fine.

              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