3

There is something weird with QGraphicsScene::removeItem, when I remove two items from the scene I get the following message:

QGraphicsScene::removeItem: item 0x5edb28's scene (0x0) is different from this scene (0x5e7790)
QGraphicsScene::removeItem: item 0x5edc18's scene (0x0) is different from this scene (0x5e7790)

Even though the two items are in the scene.

I've checked the items scene against the scene but it returns true:

if(Player->scene() == m_scene){
    m_scene->addText("Same"); // this text is added
}else{
    m_scene->addText("Different");
}

m_scene come from this class:

class Game : public QGraphicsView
{
    Q_OBJECT

    public:
        Game();

    public slots:
        void FixedUpdate();

    signals:


    private:
        QRectF *sceneSize;
        QGraphicsScene *m_scene;
        QGraphicsRectItem *m_rect;
        QTimer *m_timer;
        Character *Player;
        Character *enemy;

};

And the class Character is a class inheriting from QGraphicsPolygonItem:

class Character : public QObject, public QGraphicsPolygonItem
{
    Q_OBJECT

    public:
        Character(qreal x, qreal y, qreal w, qreal h, QString tag, QGraphicsScene *scene = 0, QGraphicsItem *parent = 0);
        Character(QRectF rectF, QString tag, QGraphicsScene *scene = 0, QGraphicsItem *parent = 0);
        Character(QString tag, QGraphicsScene *scene = 0, QGraphicsItem *parent = 0);
        void setValue(qreal x, qreal y, qreal w, qreal h);
        void setVelocity(qreal vx, qreal vy);
        void setVelocityX(qreal vx);
        void setVelocityY(qreal vy);
        void setTag(QString tag);
        qreal vx() const;
        qreal vy() const;
        qreal w() const;
        qreal h() const;
        QString tag() const;
        QGraphicsScene *currentScene() const;
        void fixedUpdate();
        void removeCharacter();

    signals:


    public slots:


    private:
        qreal m_x;
        qreal m_y;
        qreal m_w;
        qreal m_h;
        qreal m_vx;
        qreal m_vy;
        QString m_tag;
        QGraphicsScene *m_scene;
};

And this is where I call removeItem

void Game::FixedUpdate(){
    if(Player->collidesWithItem(enemy)){
        Player->setVelocityX(0);
        enemy->setVelocityX(0);

        //removeCharacter just call scene()->removeItem(this);
        Player->removeCharacter();
        enemy->removeCharacter();
    }else{
        Player->fixedUpdate();
        enemy->fixedUpdate();

    }
}

Can someone explain me why I get these messages, please?

EDIT:

Game::Game(){
    sceneSize = new QRectF(0, 0, 640, 480);
    m_scene = new QGraphicsScene(*sceneSize, this);
    setScene(m_scene);
    Player = new Character(QRectF(0, 0, 50, 50), "player", m_scene);
    Player->setVelocityX(1.5);
    //m_scene->addItem(Player);

    enemy = new Character(QRectF(500, 0, 20, 20), "enemy", m_scene);
    enemy->setVelocityX(-0.5);
    //m_scene->addItem(enemy);

    //m_scene->addText(QString::number(Player->x() + Player->vx()));

    if(Player->scene() == m_scene){
        m_scene->addText("Same");
    }else{
        m_scene->addText("Different");
    }

    m_timer = new QTimer(this);
    connect(m_timer, SIGNAL(timeout()), this, SLOT(FixedUpdate()));
    m_timer->start(1000 / 60);
}
Xlander
  • 1,331
  • 12
  • 24
  • Do you have more than one `QGraphicsScene` in your program? Also, why does your `Character` class has a `m_scene` pointer? The scene it is currently displayed in is already stored in the `QGraphicsPolygonItem` – Bowdzone Nov 11 '14 at 12:39
  • @Bowdzone, I've only one, in the `Game` class. I've put it to check if the scene `m_scene` from `Character` and scene `scene()` from its parent are the same(they are the same). – Xlander Nov 11 '14 at 12:54
  • Oh I miread the error....When you call `removeItem`, do they get removed AND you get the message or does the remove not work? If it works, is it possible you call the remove twice? – Bowdzone Nov 11 '14 at 13:01
  • "item 0x5edb28's scene (0x0) " The 0x0 is the address of the scene, so it's telling you that the scene for this item is already NULL. I suspect the problem is in code that you haven't posted here. Are you deleting the item too? If so, it will automatically be deleted from the scene and could be conflicting here. If the function that calls removeItem is called from a slot, check that only one connection to that slot exists. – TheDarkKnight Nov 11 '14 at 13:30
  • Sorry for the late reply... – Xlander Nov 12 '14 at 05:37
  • @Bowdzone, they are removed then I get the message in the "Application Output".. – Xlander Nov 12 '14 at 05:38
  • @Merlin069, They are not deleted before, I'll add the other function. – Xlander Nov 12 '14 at 05:38
  • @Merlin069, Which function is needed? The constructor? – Xlander Nov 12 '14 at 05:48
  • Huh... I've tried something... I've enclosed the function in `Game::FixedUpdate()` in an `if` statement checking if the `Character`s have scene and I don't get the messages... – Xlander Nov 12 '14 at 06:11
  • In which case, they have already been removed from the scene. If I were you, I'd investigate why, to understand the code. – TheDarkKnight Nov 12 '14 at 08:50
  • @Merlin069, I've seen it, for `1000/60` milliseconds the function is called and `removedItem` continues to be called... Thank you very much. – Xlander Nov 12 '14 at 09:06

1 Answers1

0

Finally I've found it.

It was in Game::FixedUpdate() function, it's Player->collidesWithItem(enemy) being true even after the pointers were removed from the scene. So I've put a check before it checks for collision, as so:

void Game::FixedUpdate(){
    if(Player->scene() != NULL && enemy->scene() != NULL){
        if(Player->collidesWithItem(enemy)){
            Player->setVelocityX(0);
            enemy->setVelocityX(0);

            //removeCharacter just call scene()->removeItem(this);
            Player->removeCharacter();
            enemy->removeCharacter();
        }else{
            Player->fixedUpdate();
            enemy->fixedUpdate();

        }
    }
}

Which does not give the messages after removal.

George
  • 578
  • 4
  • 21
Xlander
  • 1,331
  • 12
  • 24