QMenu 中 QAction 的所有权

Posted

技术标签:

【中文标题】QMenu 中 QAction 的所有权【英文标题】:Ownership of QAction in a QMenu 【发布时间】:2012-01-30 20:40:24 【问题描述】:

我正在使用 Qt 为应用程序构建基本 GUI,我有几个问题.. 所以我创建了 GUI,它工作正常,我想我会检查一些东西..

for(int i=0; i < 100000; i++)

    menu = new QMenu(this);
    act = new QAction("About", menu);
    menu->addAction(act);
    connect(act, SIGNAL(triggered()), this, SLOT(slotHelpAbout()));
    menuBar()->addMenu(menu)->setText("Help");

menuBar()->clear();

我使用 QMainWindow 类的 QMenuBar 并用 QMenu 填充它,QMenu 也填充了 QAction 用于将触发信号连接到几个插槽。这工作正常但是当我调用 clear 时它应该删除菜单QMenuBar 包含的/action 项.. 我正在检查任务管理器,内存使用量仍然很大.. 甚至之后:

    QList<QAction*> lst = menuBar()->actions();

    for(int i=0;i < lst.length(); i++)
    
        delete lst.at(i);
    

不应该释放 QMenus 和 QActions 使用的所有内存吗?

【问题讨论】:

对我来说大约需要 4-5 秒才能清除。但是菜单栏被清除了 是的,菜单栏已清空,但内存仍保留.. 【参考方案1】:

不,它们仍然存在于内存中,因为它们只有在 menu 被删除时才会被删除,而 menu 只有在 this 时才会被删除(假设 QMainWindow) 被删除。调用clear 不会删除它们。

clear 不这样做的原因是(除其他外)它支持如下场景:您已命名引用QAction 实例的变量,并且您希望在菜单上重新排列它们。您调用clear 将它们全部删除,然后按照您希望的顺序使用相同的操作调用addAction

如果你想直接删除它们,你可以删除菜单栏。这将递归地删除菜单栏的所有菜单和操作。调用menuBar() 会自动创建一个新的,如果它不存在,所以你甚至不必担心。

#include <QtGui>

int main(int argc, char **argv) 
  QApplication app(argc, argv);

  QMainWindow m;

  QMenu *menu = m.menuBar()->addMenu("test");
  for (int i = 0; i < 30000; ++i) 
    menu->addAction(QString::number(i));  // memory going up, up, up...
  

  delete m.menuBar();  // frees memory

  menu = m.menuBar()->addMenu("test2");  // Automatically creates new menu bar
  menu->addAction("test 2 action");

  m.show();

  return app.exec();

【讨论】:

是的,这很有趣。我不确定为什么这不起作用,但我编辑了我的答案,并使用了一个似乎确实有效的解决方案。【参考方案2】:

QMenuBar::clear 不会为您做任何事情,因为正如@Dave Mateer 所指出的,它只会从QMenuBar 中删除操作,而不会删除它们。

此外,从 QMenuBar 中删除操作列表不会导致每个 QMenu 本身被删除。

您拥有的每个QMenu 都是this 的父级,这大概是您的QMainWindow。只有当您删除QMainWindow 并且不是它的菜单栏时,它们才会被删除。您可以更改代码,以便将每个 QMenu 设置为 QMenuBar 的父级,以便删除菜单栏会删除菜单(及其操作)。或者,您可以保留指向每个单独菜单的指针并手动删除它们。

【讨论】:

是的,你说的都对。问题是父级是 QMainWindow 而不是菜单栏。谢谢!

以上是关于QMenu 中 QAction 的所有权的主要内容,如果未能解决你的问题,请参考以下文章

如何知道触发了哪个 QMenu 的动作

如何将 QMenu 中的 QAction 转换为 QWidget?

如果 QMenu 是 unique_ptr,为啥 QAction 不添加到 QMenu?

QAction QActionGroup QMenu 使用方法

防止 QMenu 在其 QAction 之一被触发时关闭

防止 QMenu 在其 QAction 之一未触发时关闭