tags:

views:

775

answers:

2

This is a rather strange situation here. I have a class which derived from QGraphicsScene

class DrawingScene : public QGraphicsScene
{
   ...
}

Whenever I add any item within the derived class, the item ended up attaching to a parent of 0x0. The thing is that despite that, the graphics item appearing within the scene as normal, and can be interacted with. For instance, this snippet of code:

QGraphicsEllipseItem * newEllipse = addEllipse(rect, pen);
qDebug() << "Scene info " << this
newEllipse->setPos(pos);
newEllipse->setZValue(100);
qDebug() << "New point added = " << newEllipse;

Here are some depug output

Scene info  DrawingScene(0x1d2ffb8) 
New point added =  QGraphicsItem(this = 0x3f0fda0 , parent = 0x0 , pos = QPointF(326, 307), z =100, flags = {"isVisible|isEnabled" })

And whenever I try to delete the item, I get a warning that the scene is different, but the item is gone nonetheless.

Am I missing something, or is QGraphicsScene not meant to be derived from in the first place?

Edit: Code for deletion

The QGraphicsItems, are added to QMap for fast mapping purpose and to disable a group of them at a go. So this is how the item is added to the scene (as above) and the Map

int SceneTrackerData::addLink(QGraphicsLineItem * newLink)
{
    links_.insert(currentLinkID_, newLink);

    qDebug() << links_;

    // Store the ID of the newly added link and increment link count
    int thisLinkID = currentLinkID_; 
    currentLinkID_++;

    newLink->setData(LinkData::LinkID, QVariant(thisLinkID));


    qDebug() << "Link " << thisLinkID << " connecting " << newLink->data(0).toInt()
          << " and " << newLink->data(1).toInt() << " added.";


    return thisLinkID;
}

Here's the deletion:

SceneManager contains an instance of DrawingScene, which inherits QGraphicsScene

void SceneManager::DeleteLink(int linkID, int startNodeID, int endNodeID)
{
    // sceneData_ wraps the QMap<int, QGraphicsItem>.
    // This calls SceneTrackerData::deleteLink(int) (below)
    QGraphicsLineItem * link = sceneData_->deleteLink(linkID);

qDebug() << "Link to remove " << link;

    // scene_ is an instance of DrawingScene, which inherits QGraphicsItem, so
    // this is just a vanila call to QGraphicsScene::removeItem()
    scene_->removeItem(link);

    // release the link from memory
    delete link;

    emit informLinkDeleted(startNodeID, endNodeID);
}

QGraphicsLineItem* SceneTrackerData::deleteLink(int linkid)
{
    qDebug() << "deleting link of id " << linkid;
    QGraphicsLineItem * line = links_.take(linkid);
    qDebug() << links_;
    return line;

}

The warning is

QGraphicsScene::removeItem: item 0x32fa7d8's scene (0x0) is different from this scene (0x1aabb60)

More edits

After adding some lines and ellipse items, this is how the scene->items() looks like after adding the objects. They all have parent = 0x0

(QGraphicsItem(this =0x3b980a8, parent =0x0, pos =QPointF(0, 0),
 z =-1, flags = {"isVisible|isEnabled" }), 

QGraphicsItem(this =0x3c32980, parent =0x0, pos =QPointF(326, 303), 
z =100, flags = {"isVisible|isEnabled" }), 

QGraphicsItem(this =0x3b9a1e0, parent =0x0, pos =QPointF(420, 410),
z =100, flags = {"isVisible|isEnabled" }), 

QGraphicsItem(this =0x3f0ffc0, parent =0x0, pos =QPointF(411, 395), 
z =100, flags = {"isVisible|isEnabled" }),

 QGraphicsItem(this =0x3cf4600, parent =0x0, pos =QPointF(327, 302), 
 z =0, flags = {"isVisible|isEnabled" }))

What I am trying to delete is QGraphicsItem(this =0x3cf4600), and here's the outcome:

Link to remove  QGraphicsItem(this = 0x3cf4600 , parent = 0x0 , pos = QPointF(327,
302), z =0, flags = {"isVisible|isEnabled" })

Before removing:

 QGraphicsScene::removeItem: item 0x3cf4600's scene (0x0) is different from this scene 
 (0x1e2ffb8)

 Scene after moving 
(QGraphicsItem(this =0x3b980a8, parent =0x0, pos =QPointF(0, 0), 
 z =-1, flags = {"isVisible|isEnabled" }), 

QGraphicsItem(this =0x3c32980, parent =0x0, pos =QPointF(326, 303), 
z =100, flags = {"isVisible|isEnabled" }), 

QGraphicsItem(this =0x3b9a1e0, parent =0x0, pos =QPointF(420, 410), 
z =100, flags = {"isVisible|isEnabled" }), 

QGraphicsItem(this =0x3f0ffc0, parent =0x0, pos =QPointF(411, 395), 
z =100, flags = {"isVisible|isEnabled" }))

The behaviour is correct. I am puzzled why the warning is evening triggered at all.

+1  A: 

There is nothing wrong with this code. The item does not get attached to a parent of 0x0. The item gets attached to the scene, which means it does not have another item as its parent. This results in the item having NULL as its parent. The 0x0 you see is not size, it is NULL pointer.

I recommend reading The Graphics View Framework. It is a good place to start, and also a good place to refer when you encounter an error.

erelender
Meaning that the Scene points to parent, not the item points to parent
Extrakun
+1  A: 

I believe that the "parent = 0x0" piece of the debug output is referring to a parent graphics item (as opposed to a parent QObject, for example). As mentioned in the QGraphicsitem documentation, graphics items can have parent items (which means that transformations applied to the parent will also be applied to the children).

Calling addEllipse(...) will create a stand-alone graphics item, with no parent (but will add it to the scene).

Regarding your deletion code, what does the QGraphicsItem::scene() return

  1. Immeadiately after creating the graphics item with addEllipse()
  2. Right before removing the graphics item?

If it returns NULL right after creation, then something is going wrong in the creation of the graphics item. If it's later, then something is borked in your map storage & retrieval code.

I'm a but confused as to why you're storing pointers to QGraphicsLineItems, and creating QGraphicsEllipseItems? I assume this is a typo?

Thomi
Hi, thanks for your offer. I have posted the deletion code.
Extrakun
Yes, typo, but both objects yield the same problem so I was confused while posting the code.
Extrakun
Hi, I have added the output dump of the scene. The item is removed correctly, but still a warning is thrown.
Extrakun