3

I've subclassed QGraphicsItem into my own custom class, Hexagon. When I try to use a function such as QGraphicsView::itemAt, or QGraphicsScene::itemAt, it won't return any of my Hexagon objects because the function instead looks for QGraphicsItems.
How can I tell it to look for Hexagon objects instead? Or do I need to change something in my Hexagon class? Or even re-implement itemAt()?

Currently, I'm also subclassing QGraphicsView, particlarly mousePressedEvent to get some info about the Hexagon object that is clicked on.

void LatticeView::mousePressEvent(QMouseEvent *event)
{
    Hexagon *hexagon = itemAt(event->pos());
    ...
}

But when I try to compile, I get the following error:

invalid conversion from 'QGraphicsItem*' to 'Hexagon*'

What I want is to be able to get the Hexagon object that is clicked on so that I can access some variables I've defined in the Hexagon class that are not implicit in the QGraphicsItem class.

Mat
  • 202,337
  • 40
  • 393
  • 406
Anthony
  • 8,570
  • 3
  • 38
  • 46
  • what do you mean "won't return any of my Hexagon objects"? Sounds like you just need to cast back and forth from QGraphicsItem* to Hexagon*. – Guy Sirton Jan 29 '12 at 03:20
  • Have you implemented boundingRect()? – Arnold Spence Jan 29 '12 at 03:36
  • I mean that "itemAt()" has a return type of QGraphicsItem, so if I call itemAt() -- for example, in the QGraphicsItem's mousePressedEvent function -- it doesn't return my Hexagon objects because the return type is QGraphicsItem. You're right, I probably do need to just cast back and forth between QGraphicsItem and Hexagon, but I don't know how or where I'd do that. I had thought it would be enough if I just inherited QGraphicsItem in my Hexagon class, but obviously it's not. Thanks! – Anthony Jan 29 '12 at 03:55
  • Arnold, yes, I have implemented it. Pretty sure it's not the issue. – Anthony Jan 29 '12 at 03:56
  • Shoot, I meant (in my above comment) ***for example, in the QGraphicsScene's/View's mousePressedEvent function. – Anthony Jan 29 '12 at 04:27
  • I'm having trouble understanding your issue. Is `itemAt()` returning null or a value? – Arnold Spence Jan 29 '12 at 06:19
  • This is what I get: "error: invalid conversion from 'QGraphicsItem*' to 'Hexagon*'. I'll edit my question to provide additional info. – Anthony Jan 29 '12 at 06:24

1 Answers1

1

To get this to work, you would need to cast the pointer before assigning it to a pointer variable of another type..

Hexagon *hexagon = (Hexagon*)itemAt(event->pos());

But there is danger here since itemAt() may return NULL or the item may not be a Hexagon item.

In fact, you should use the C++ style cast like this:

Hexagon *hexagon = dynamic_cast<Hexagon*>(itemAt(event->pos()));
if (hexagon != NULL)
{
   hexagon->hexagonMethod();
}

This will require Run-time type information to be available through your compiler.

There is also a QGraphicsItem function available called type() which will allow you to use qgraphicsitem_cast() but that requires a little extra work involving defining an enum.

One additional thing to watch out for. Depending on how your scene and items are consuming mouse events, you may not always see your override of mousePressEvent() get called when you expect it to since the mouse event may never get up to the view if it is consumed by something in the scene.

Arnold Spence
  • 21,942
  • 7
  • 74
  • 67
  • Brilliant. That makes sense. Thank you so much! I used your second bit of code, and it works perfectly. Would you mind saying a bit more about what you said, "This will require Run-time type information to be available through your compiler"? I don't quite understand. If it matters, I'm using Qt Creator. – Anthony Jan 29 '12 at 09:14
  • `dynamic_cast` requires run-time type information (RTTI) which is provided by the compiler and is sometimes not enabled by default. This shouldn't be a concern with QtCreator and g++. You can read some more about it all here: http://www.cplusplus.com/doc/tutorial/typecasting – Arnold Spence Jan 29 '12 at 17:48