C++ 子类化QGraphicsSitem使我无法在QGraphicscene/视图上使用itemAt()

C++ 子类化QGraphicsSitem使我无法在QGraphicscene/视图上使用itemAt(),c++,qt,C++,Qt,我已经将QGraphicsItem子类化到我自己的自定义类Hexagon中。当我尝试使用诸如QGraphicsView::itemAt或qgraphicscene::itemAt之类的函数时,它不会返回任何Hexagon对象,因为该函数会查找qgraphicssitems 我如何告诉它寻找Hexagon对象?或者我需要更改我的Hexagon类中的某些内容吗?或者甚至重新实现itemAt() 目前,我还在对QGraphicsView进行子类化,特别是mousePressedEvent,以获取有关单

我已经将QGraphicsItem子类化到我自己的自定义类Hexagon中。当我尝试使用诸如
QGraphicsView::itemAt
qgraphicscene::itemAt
之类的函数时,它不会返回任何
Hexagon
对象,因为该函数会查找
qgraphicssitems

我如何告诉它寻找
Hexagon
对象?或者我需要更改我的
Hexagon
类中的某些内容吗?或者甚至重新实现
itemAt()

目前,我还在对
QGraphicsView
进行子类化,特别是
mousePressedEvent
,以获取有关单击的
Hexagon
对象的一些信息

void LatticeView::mousePressEvent(QMouseEvent *event)
{
    Hexagon *hexagon = itemAt(event->pos());
    ...
}
但是,当我尝试编译时,会出现以下错误:

从“QGraphicsItem*”到“Hexagon*”的转换无效


我想要的是能够获得单击的
Hexagon
对象,这样我就可以访问我在
Hexagon
类中定义的一些变量,这些变量在
QGraphicsItem
类中不是隐式的,在将指针分配给其他类型的指针变量之前,需要强制转换指针

Hexagon *hexagon = (Hexagon*)itemAt(event->pos());
但是这里存在危险,因为
itemAt()
可能返回
NULL
,或者该项可能不是
Hexagon

实际上,你应该使用这样的C++样式:

Hexagon *hexagon = dynamic_cast<Hexagon*>(itemAt(event->pos()));
if (hexagon != NULL)
{
   hexagon->hexagonMethod();
}
Hexagon*Hexagon=dynamic_cast(itemAt(event->pos());
如果(六边形!=NULL)
{
六边形->六边形方法();
}
这需要运行时类型信息通过编译器提供

还有一个名为
QGraphicsItem
的函数,它允许您使用
QGraphicsItem_cast()
,但这需要一些额外的工作,包括定义
enum


还有一件事需要注意。根据您的场景和项目使用鼠标事件的方式,您可能不会总是看到您对
mousePressEvent()
的覆盖在您期望的时候被调用,因为如果鼠标事件被场景中的某个对象使用,它可能永远不会到达视图。

您的意思是“不会返回任何我的六边形对象”?听起来你只需要来回转换QGraphicsItem*到Hexagon*。你实现了boundingRect()吗?我的意思是“itemAt()”的返回类型是QGraphicsItem,所以如果我调用itemAt()——例如,在QGraphicsItem的mousePressedEvent函数中——它不会返回我的Hexagon对象,因为返回类型是QGraphicsItem。你是对的,我可能确实需要在QGraphicsItem和Hexagon之间来回转换,但我不知道如何或在哪里进行转换。我原以为只要在Hexagon类中继承QGraphicsItem就足够了,但显然不行。谢谢阿诺德,是的,我已经实施了。我的意思是(在我上面的评论中)***例如,在qgraphicscene/View的mousePressedEvent函数中。这是有道理的。非常感谢你!我用了你的第二段代码,它工作得很好。您是否介意多说一点您所说的“这将要求运行时类型信息可以通过编译器获得”?我不太明白。如果重要的话,我使用的是Qt Creator。
dynamic_cast
需要运行时类型信息(RTTI),它由编译器提供,有时默认情况下不启用。这与QtCreator和g++无关。您可以在这里阅读更多关于这一切的信息: