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); }
-
@black_gay said in Collisions with custom QGraphicsItem that inherits from QObject:
public QObject, public QGraphicsItem
So my question is, how do i prevent the shift or retrive the correct address from collidingItems()?
You can't - or invent something other than c++
Since QObject needs some memory, esp. when you add functions for QObject the addresses differ. -
@black_gay said in 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).
class CustomRect : public QObject, public QGraphicsItem
Apart from the answer @Christian-Ehrlicher has given to the question you ask. The above is what QGraphicsObject Class does:
The QGraphicsObject class provides a base class for all graphics items that require signals, slots and properties
and is what you should use in preference to rolling your own.
-
@JonB But it will behave exactly as his class wrt to the pointers:
class Q_WIDGETS_EXPORT QGraphicsObject : public QObject, public QGraphicsItem
-
@Christian-Ehrlicher said in Collisions with custom QGraphicsItem that inherits from QObject:
@JonB But it will behave exactly as his class wrt to the pointers:
Absolutely true! Hence I said
Apart from the answer @Christian-Ehrlicher has given to the question you ask.
This is just a suggestion for if OP does want equivalent for the
class CustomRect : public QObject, public QGraphicsItem
. Not that it will change any behaviour wrt to pointers question.