【问题标题】:How to delete all QGraphicsItem from QGraphicsScene如何从 QGraphicsScene 中删除所有 QGraphicsItem
【发布时间】:2011-11-17 20:48:56
【问题描述】:

我从QGraphicsScene 编写了一个派生类。有时我需要从场景中移除所有项目,并且我希望这些项目被物理销毁(调用析构函数)。我尝试了以下方法:

QList<QGraphicsItem*> all = items();
for (int i = 0; i < all.size(); i++)
{
    QGraphicsItem *gi = all[i];
    removeItem(gi);
    delete gi; // warning at this line
}

Qt Creator 发出警告:警告:C4150:删除指向不完整类型“QGraphicsItem”的指针;没有调用析构函数

我不确定这是为什么。 QGraphicsItem 具有虚拟析构函数,因此应从内存中删除项目。

如果这不是正确的方法,我如何从QGraphicsScene 中删除所有QGraphicsItems?请注意,我知道当场景被删除时,所有项目也将被删除。但我想从场景中删除项目并绘制其他项目。我希望从内存中删除已删除的项目。

【问题讨论】:

    标签: c++ qt incomplete-type


    【解决方案1】:

    您可以使用QGraphicsScene::clear() 删除和删除所有项目。

    【讨论】:

    • 注意 clear 似乎没有调用 removeItem 或触发 itemChange 事件 (ItemSceneChange)。查看源代码,如果您的代码依赖于删除事件来集中一些清理代码等,最好对每个顶级项目进行子类化并使用removeItem,以最大限度地重用。可能更重,但乍一看似乎很合理。如果这是一个坏主意,请发表评论。
    • 请注意,QGraphicsScene::clear() 将向所有QGraphicsItems 调用delete,即使他们是班级成员!显然,如果那些不是指针,这将导致异常。
    【解决方案2】:

    就像 jpalecek 指出的那样,您缺少头文件。你应该接受他的回答。我只想指出两个潜在的问题:

    首先,您无需致电QGraphicsScene::removeItem()QGraphicsItem::~QGraphicsItem() 为你做这件事。

    其次。如果您将任何QGraphicsItem 放在其他人的内部,请小心。也就是说,您的项目是其他项目的子项。 QGraphicsItem 的析构函数会自动删除其所有子级。因此,当您遍历从QGraphicsScene 返回的项目时,您最终可能会删除已被其父项删除的子项。例如,假设您有 2 个项目,A 和 B,并且 B 是 A 的子项。当您删除 A 时,B 会自动删除。然后你到 B 并尝试删除它。轰隆隆!

    一种更安全的方法是测试该项目是否是顶级项目,即它没有父项:

    QList<QGraphicsItem*> all = items();
    for (int i = 0; i < all.size(); i++)
    {
        QGraphicsItem *gi = all[i];
        if(gi->parentItem()==NULL) {
            delete gi;
        }
    }
    

    【讨论】:

      【解决方案3】:

      你必须

      #include <QGraphicsItem>
      

      在那个文件中。否则,编译器不知道QGraphicsItem 是什么,它有一个虚拟析构函数等等。

      【讨论】:

        猜你喜欢
        • 2015-11-01
        • 1970-01-01
        • 2019-08-11
        • 1970-01-01
        • 1970-01-01
        • 2019-05-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多