'Collisions with custom QGraphicsItem that inherits from QObject
I made QGraphicsItem (named "player") and a custom QGraphicsItem (named "customRect"), which inherits from QObject (because inside the class i use QTimer). Then, by using collidingItems(), i list all the items player collides with. The thing i dont understand is why, when collision with customRect occurs, the address returned by collidingItems() is different than customRect (shifted by 16 bytes). In my case address of customRect at creation is 0x1ca091c5450, and collidingItems() returns 0x1ca091c5460 (while when 2 non-custom QGraphicsItems collide, there is no such shift). Through trial and error i found out that Q_OBJECT macro shifts the address. So my question is, how do i prevent the shift or retrive the correct address from collidingItems()?
My code is:
//main:
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Game g;
QTimer* timer = new QTimer(&g);
QObject::connect(timer, &QTimer::timeout, &g, &Game::advance);
timer->start(1000/3);
return a.exec();
}
//Game header:
class Game : public QGraphicsScene
{
Q_OBJECT
public:
explicit Game();
void keyPressEvent(QKeyEvent *event);
void advance();
signals:
private:
QGraphicsRectItem* player;
QGraphicsRectItem* rectItem;
CustomRect* customRect;
QGraphicsView* m_view;
};
//game cpp:
#include "game.h"
#include <QGraphicsItemGroup>
#include <iostream>
Game::Game()
{
player = new QGraphicsRectItem();
m_view = new QGraphicsView(this);
m_view->setSceneRect(QRectF(0,0,800,600));
this->setBackgroundBrush(Qt::black);
m_view->setScene(this);
m_view->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
m_view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
m_view->setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
m_view->setViewportUpdateMode(QGraphicsView::NoViewportUpdate);
m_view->show();
player->setRect(0,0,100,100);
player->setBrush(Qt::red);
player->setPos(400,300);
player->setFocus();
this->addItem(player);
player->setZValue(10);
player->setTransformOriginPoint(player->boundingRect().center());
customRect = new CustomRect;
customRect->setPos(400,300);
this->addItem(customRect);
}
void Game::advance()
{
std::cout << "customRect: " << customRect << "\n";
QList<QGraphicsItem*> list = player->collidingItems();
for (int i = 0; i < list.size(); ++i) {
std::cout << "i: " << list.at(i) << "\n";
}
}
//customRect header:
class CustomRect : public QObject, public QGraphicsItem
{
Q_OBJECT
public:
explicit CustomRect (QGraphicsItem *parent = nullptr);
virtual QRectF boundingRect() const;
virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
private:
QRectF rect;
};
//customRect cpp:
CustomRect::CustomRect(QGraphicsItem *parent) : QGraphicsItem{parent}
{
std::cout << "this: " << this << "\n";
rect.setRect(0,0,100,100);
std::cout << "rect: " << &rect << "\n";
}
QRectF CustomRect::boundingRect() const
{
return rect;
}
void CustomRect::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
QPen towerPen(Qt::green, 3);
painter->setPen(towerPen);
painter->setRenderHint(QPainter::Antialiasing);
painter->drawRect(rect);
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
