【问题标题】:Memoryleak with QListWidget addItem() + setItemWidget()内存泄漏与 QListWidget addItem() + setItemWidget()
【发布时间】:2014-08-27 22:17:24
【问题描述】:

当我按下一个键时,将会有一个对引擎的查询。通过添加一个项目并设置小部件,结果将被放入QListWidget。不知何故,这会导致大量内存溢出,甚至使我的机器崩溃。但我没有得到错误。 clear() 不会删除传递给QListWidget 的项目和setItemWidget() 设置的小部件。我什至试图自己删除它们(评论),但仍然有内存泄漏。我猜错误在if (!results.empty())-block 中,因为注释掉它会堵塞内存泄漏。

void Widget::onTextEdited(const QString & text)
{
    //  QListWidgetItem * takenItem;
    //  while (takenItem = _results->takeItem(0)){
    //      delete _results->itemWidget(takenItem);
    //      delete takenItem;
    //  }
    _results->clear();  _results->hide();

    if (!text.isEmpty())
    {
        const std::vector<const Items::AbstractItem *> results = _engine.request(text);
        if (!results.empty())
        {
            for (auto i : results){
                QListWidgetItem *lwi = new QListWidgetItem;
                _results->addItem(lwi);
                ListItemWidget *w = new ListItemWidget;
                w->setName(i->name());
                w->setTooltip(i->path());
                _results->setItemWidget(lwi, w);
            }
            _results->setFixedHeight(std::min(5,_results->count()) * 48); // TODO
            _results->show();
        }
    }
    this->adjustSize();

}

【问题讨论】:

    标签: c++ qt memory-leaks qt5


    【解决方案1】:

    您绝对应该使用内存泄漏检测工具,而不是四处猜测:)

    UPDATE:clear() 只删除项目,但不删除属于它的小部件。如果 QListWidget 被删除,小部件将被删除。

    clear() 确实删除了属于它的项目和小部件。你提到注释掉 if(!results.empty()) 解决了这个问题。我在 setItemWidget 部分看不到任何问题。所以我认为问题出在其他地方,也许是ListItemWidget。你试试用QLabel 替换ListItemWidget 看看会发生什么。例如:

    QListWidgetItem *lwi = new QListWidgetItem;
    _results->addItem(lwi);
    //ListItemWidget *w = new ListItemWidget;
    //w->setName(i->name());
    //w->setTooltip(i->path());
    QLabel *w = new QLabel;
    w->setText("Hello");
    _results->setItemWidget(lwi, w);
    

    【讨论】:

    • 我刚试过。内存泄漏仍然存在。 Valgrind 告诉我没有错误。
    • @ManuelSchneid3r,评论 QLabel 和 setItemWidget 部分怎么样,只留下前两行(新的 QListWidgetItem 和 addItem)。是什么告诉你存在内存泄漏?程序崩溃了?
    • 发现:clear() 不会删除小部件。它只是删除小部件。感谢您的帮助,
    • @ManuelSchneid3r,我的错!我认为 clear() 确实删除了小部件,因为 w 在调用 setItemWidget() 后有一个父级。显然 listWidget 只会在它自己被删除后才会删除小部件。因此,在您的情况下,小部件将继续占用内存,直到 listWidget 被删除。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-10-16
    • 2019-08-08
    • 2012-08-21
    • 2016-01-25
    • 1970-01-01
    • 2015-04-15
    • 2014-03-26
    相关资源
    最近更新 更多