如何删除具有一些子项成员的QGraphicsItem?

3

我有一个自定义项,它继承了QGraphicsItem。它有一些子图形项作为成员变量。我应该按照什么顺序从场景中删除这些项,如何删除它们?


1
请注意,将它们添加为成员并不意味着它们是Qt所定义的“子项”。您必须在即将成为子项的项目中设置一个“父项”,即自己(this),可以在构造函数中或之后使用childItem->setParent(this)来实现。 - leemes
它们是成员变量,并以主项作为父项。 - fatma.ekici
然后一切都好了。但是这个评论可能对未来的读者很重要,因为这可能是一个容易犯的错误。 - leemes
1个回答

7
像这样创建您的会员图形项:
class MyClass : public QGraphicsItem
{
    ...
private:
    
    SomeKindOfGraphicsItem* _item1;
    SomeOtherGraphicsItem* _item2;
}

MyClass::MyClass( ... ) :
    QGraphicsItem( ... ),
    _item1( new SomeKindOfGraphicsItem( ..., this ) ),
    _item2( new SomeOtherGraphicsItem( ..., this ) )
{
    ...
}

在这种情况下,只需从场景中删除父项(例如本例中的MyClass),就足以删除所有子项:

void QGraphicsScene::removeItem(QGraphicsItem * item)

将项目item及其所有子项从场景中删除。item的所有权将传递给调用者(即,当销毁时,QGraphicsScene将不再删除item)。

此外,当MyClass对象被删除时,它将通过Qt机制删除所有子项:

QGraphicsItem::~QGraphicsItem() [virtual]

销毁QGraphicsItem及其所有子项。如果此项当前与场景相关联,则在删除之前将从场景中删除该项。

注意:在销毁项之前,从QGraphicsScene中删除项更为高效。


我需要在析构函数中删除子项吗?实际上这可能导致了问题。 - fatma.ekici
2
@fatma.ekici 不需要手动删除,这是自动完成的。如果您手动删除,会出现双重删除,导致程序崩溃!顺便说一下,对于小部件类型和其他QObject类型也是如此。它们都形成一个;如果从树中删除一个节点,则所有子节点将被递归删除;Qt会自动完成此过程。您只需要确保它们树中,这可以通过在构造函数中传递父对象来实现(代码中成员初始化列表中的this是关键)。 - leemes
我在主项的析构函数中没有删除任何子项。但是当我从场景中移除主项后调用delete mainItem时,程序会崩溃。 - fatma.ekici
如果我不调用delete mainItem,只是从场景中删除该项,则该项的某些部分仍然留在场景中。 - fatma.ekici
谢谢@leemes。我解决了这个问题。原来是我在paint函数中意外地创建了一个子成员。简而言之,不需要为子项调用removeItem,也不需要在父项的析构函数中删除子项。 - fatma.ekici
感谢您的帖子,最简单的方法是直接删除对象。在我的项目中,如果我在删除之前调用removeItem,它会导致一些内存泄漏,不知道为什么。(似乎在removeItem之后,代码会搜索已删除的childItem) - Enzojz

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