【问题标题】:QToolBar children list always growing. Qt memory leak?QToolBar 子列表总是在增长。 Qt内存泄漏?
【发布时间】:2016-02-04 14:17:47
【问题描述】:

我希望只有一个 QToolBar 实例,并在我的应用程序执行期间对其进行多次修改。但是,我担心 Qt 完成的内存管理。

考虑以下几点:

QToolBar toolBar;
std::cout << toolBar.actions().size() << std::endl; // Prints 0
toolBar.addSeparator(); // will add an action
std::cout << toolBar.actions().size() << std::endl; // Prints 1
toolBar.clear();
std::cout << toolBar.actions().size() << std::endl; // Prints 0 again. Good!

最初,QToolBar 中的操作列表是空的。因此第一个 cout 打印“0”。通过“addSeparator”将一个内部操作添加到该列表中。所以第二个 cout 打印“1”。最后,“清除”,如预期的那样,删除所有操作,最后一个 cout 再次打印“0”。

现在,考虑一下“子列表”会发生什么:

QToolBar toolBar;
std::cout << toolBar.children().size() << std::endl; // Prints 3. Why?
toolBar.addSeparator(); // will add an action
std::cout << toolBar.children().size() << std::endl; // Prints 5. "addSeparator" has added two children.
toolBar.clear();
std::cout << toolBar.children().size() << std::endl; // Still prints 5. "Clear" did not remove any children!

最初,children 列表的大小为 3。然后我调用“addSeparator”并将两个人添加到该列表中。好吧,我可以忍受。然而,在调用“清除”这些家伙之后,这些家伙并没有被删除。对于每个“addSeparator”或“addWidget”调用,都会添加两个孩子,并且永远不会删除它们。

我正在使用 Qt 5.4.1 for MSVC 2013, Windows。


编辑:添加peppe 建议的代码。请阅读 cmets 行。

QToolBar toolBar;
std::cout << toolBar.children().size() << std::endl; // Prints 3.
toolBar.addSeparator();
std::cout << toolBar.children().size() << std::endl; // Prints 5. "addSeparator" has added two children.

auto actions = toolBar.actions();

for (auto& a : actions) {
    delete a;
}

std::cout << toolBar.children().size() << std::endl; // Now this prints 4. Shouldn't be 3?

【问题讨论】:

    标签: c++ qt memory-leaks qt5 qtoolbar


    【解决方案1】:

    看一下addSeparator的实现:

    QAction *QToolBar::addSeparator()
    {
        QAction *action = new QAction(this);
        action->setSeparator(true);
        addAction(action);
        return action;
    }
    

    这会创建一个新的子 QAction 并将其添加到小部件的操作列表中。 clear 清除动作列表,但不破坏动作!因此,它们仍将作为工具栏的子项存在。

    Qt 不知道您没有在其他地方使用这些操作——它们旨在用于多个小部件。如果要回收该内存,请删除 addSeparator 返回的操作。

    【讨论】:

    • 假设工具栏子列表的大小为x。然后我多次致电toolBar.addSeparator()。之后,我遍历toolBar.actions() 返回的列表并删除该列表上的每个指针。工具栏子列表的大小必须再次为x?恐怕这不会发生。
    • 你能修改你的问题,显示你这样做的代码吗?
    • 完成。现在我不再调用toolBar.clear();,而是遍历操作列表并删除每个操作。请阅读 cmets 行。
    • 如果您在获取孩子列表之前调用QCoreApplication::processEvents,它仍然这样做吗?认为其中一个对象已计划删除,而不是刚刚删除。
    猜你喜欢
    • 1970-01-01
    • 2020-03-11
    • 2016-07-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-13
    • 2023-03-19
    相关资源
    最近更新 更多