我有自己的QGraphicsPixmapItem,它由QGraphicsPixmapItem和一些附加属性(如std::string name
class MyQGraphicsPixmapItem : public QGraphicsPixmapItem {
private:
std::string name;
...
public:
MyQGraphicsPixmapItem();
explicit MyQGraphicsPixmapItem(const QPixmap &pixmap, std::string name, QGraphicsItem *parent = nullptr);
std::string getname() const;
...
};
构造函数是这样的:
MyQGraphicsPixmapItem::MyQGraphicsPixmapItem(const QPixmap &pixmap, std::string name, QGraphicsItem *parent) :
QGraphicsPixmapItem(pixmap, parent), name(name){
...
}
问题是:我有一堆MyQGraphicsPixmapItem
我添加到QGraphicsScene
中。但是当我使用方法QGraphicsScene::itemAt(const QPointF &position, const QTransform &deviceTransform) const
时,它返回QGraphicsItem*
(而不是MyQGraphicsPixmapItem*
)。所以我想我必须使用向下投射的权利?但即使在像这样使用羽绒铸造之后:
MyQGraphicsPixmapItem* item = static_cast<MyQGraphicsPixmapItem*>(QGraphicsScene::itemAt(...));
std::cout << item->getName() << std::endl;
它返回一个空字符串(就像构造函数中所示没有this.name = name;
一样)。
总之,我在具有正确name
初始化的QGraphicsScene
中创建一堆MyQGraphicsPixmapItem
(我在创建QGraphicsScene
期间用std::cout
对其进行了测试),但是当我想随机选择一个QGraphicsItem
并检查他的名字时,我使用该QGraphicsScene::itemAt
,尽管进行了向下投射,但每次std::string name
清空时都会向后退。 另外,我非常确定我用正确的论点指向正确的MyQGraphicsPixmapItem
(我已经做了一些测试)。 我也在考虑在我的类"MyScene"中实现正确的"itemAt"(你猜对了,它继承了"QGraphicsScene"),但我会再次使用type_casting。
PS :告诉我我的问题是否被问得很好。
真诚的你
你应该能够使用dynamic_cast
但Qt也提供了自己的强制转换qgraphicsitem_cast
如果项目是该类型或0,则返回转换为给定类型的项目。
文档说明:
若要使此函数与自定义项正常工作,请重新实现 每个自定义 QGraphicsItem 子类的 type() 函数。
示例类:
class MyQGraphicsPixmapItem : public QGraphicsPixmapItem
{
public:
...
enum { Type = UserType + 1 };
int type() const override { return Type; }
...
};
示例测试:
MyQGraphicsPixmapItem myItem;
qDebug() << &myItem;
QGraphicsItem *item = &myItem;
MyQGraphicsPixmapItem *castedItem = qgraphicsitem_cast<MyQGraphicsPixmapItem*>(item);
if (castedItem) {
qDebug() << castedItem;
} else {
qWarning() << "casting failed";
}
更新:
QGraphicsScene::itemAt 返回指定位置最顶层的可见项,如果此位置没有项,则返回 0。
如果您用qgraphicsitem_cast
验证您成功铸造,即它返回指针而不是 0,那么您确实收到了您的自定义项目,而不是其他图形项目。然后,如果您为所有自定义项定义了名称,则它应该定义名称而不是空字符串。
要进一步调试此问题,您可以使用 QGraphicsScene::items 列出场景中QGraphicsScene::itemAt
认为可见的所有项目。在循环中执行强制转换并打印出所有自定义项的名称。
我想到的一件事是,这与调用 itemAt 时使用的坐标有关。例如,当您用鼠标单击然后查询项目坐标中的场景而不是场景坐标时,您正在进行铸造。QGraphicsSceneMouseEvent::scenePos 返回鼠标光标在场景坐标中的位置。也许您没有得到您认为的自定义项目?