继承QGraphicsItem会阻止我在QGraphicsScene/View上使用itemAt()方法

3
我将QGraphicsItem子类化为自己的自定义类Hexagon。当我尝试使用如QGraphicsView :: itemAt或QGraphicsScene :: itemAt之类的函数时,它不会返回我的Hexagon对象,因为该函数实际上寻找的是QGraphicsItems。
我该如何告诉它查找Hexagon对象?或者我需要更改Hexagon类中的某些内容吗?甚至重新实现itemAt()?
目前,我还在子类化QGraphicsView,特别是mousePressedEvent以获取有关所单击的Hexagon对象的一些信息。
void LatticeView::mousePressEvent(QMouseEvent *event)
{
    Hexagon *hexagon = itemAt(event->pos());
    ...
}

但是,当我尝试编译时,出现了以下错误:
无效的从'QGraphicsItem*'到'Hexagon*'的转换
我想要的是能够获取被单击的Hexagon对象,这样我就可以访问一些在Hexagon类中定义的变量,这些变量在QGraphicsItem类中不是隐含的。

你实现了boundingRect()吗? - Arnold Spence
我的意思是,"itemAt()" 的返回类型是 QGraphicsItem,所以如果我调用 itemAt() -- 例如,在 QGraphicsItem 的 mousePressedEvent 函数中 -- 它不会返回我的 Hexagon 对象,因为返回类型是 QGraphicsItem。你说得对,我可能确实需要在 QGraphicsItem 和 Hexagon 之间进行强制转换,但我不知道在哪里或如何做到这一点。我曾经认为只需在我的 Hexagon 类中继承 QGraphicsItem 就足够了,但显然不是这样。谢谢! - Anthony
Arnold,是的,我已经实现了它。非常确定这不是问题所在。 - Anthony
抱歉,在我上面的评论中,我的意思是例如在QGraphicsScene/View的mousePressedEvent函数中。 - Anthony
我不太明白你的问题。itemAt() 是返回 null 还是一个值? - Arnold Spence
显示剩余2条评论
1个回答

1
要使其工作,您需要在将指针分配给另一种类型的指针变量之前对其进行转换。
Hexagon *hexagon = (Hexagon*)itemAt(event->pos());

但是这里存在危险,因为 itemAt() 可能会返回 NULL 或者该项可能不是一个 Hexagon 项。

实际上,你应该使用 C++ 类型转换,像这样:

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

这将需要在编译器中通过运行时类型信息来实现。

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

还有一件需要注意的事情。根据场景和项如何消耗鼠标事件,当您期望时,您的mousePressEvent()重写可能不会始终被调用,因为如果由场景中的某些内容消耗了鼠标事件,则鼠标事件可能永远不会到达视图。


太棒了,这很有道理。非常感谢!我使用了您的第二段代码,并且它完美地工作。您能否多说一点关于您所说的“这将需要通过编译器可用的运行时类型信息”?我不太理解。如果有关系的话,我正在使用Qt Creator。 - Anthony
dynamic_cast 需要运行时类型信息(RTTI),这由编译器提供,有时默认情况下未启用。但在 QtCreator 和 g++ 中不应该成为问题。您可以在此处阅读更多相关信息:http://www.cplusplus.com/doc/tutorial/typecasting - Arnold Spence

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接