简体   繁体   中英

Ownership of QAction in a QMenu

I was using Qt to build a basic GUI for an application and I have a few questions.. So I created the GUI, it works fine and I thought I would check something..

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();

I use the QMenuBar of the QMainWindow class and fill it up with QMenu which are also filled up with QAction for wich I connect the triggered signal to a few slots.. This works fine but when I call clear it should delete the menu/action items contained by QMenuBar.. I am checking in task manager and the memory usage is still huge.. Even after:

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

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

Shouldn't all memory used by the QMenus and QActions be freed ?

No, they still exist in memory because they will only be deleted when menu is deleted, and menu is only deleted when this (assuming a QMainWindow ) is deleted. Calling clear does not delete them.

The reason clear doesn't do this is because (among other things) it supports a scenario like the following: you have named variables referring to the QAction instances, and you want to rearrange them on your menu. You call clear to remove them all, then call addAction with those same actions in the order you desire.

If you want to delete them directly, you can just delete the menu bar. This will delete all the menus and actions parented to the menu bar recursively. Calling menuBar() automatically creates a new one if it does not exist, so you don't even have to worry about that.

#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();
}

QMenuBar::clear will do nothing for you since, as pointed out by @Dave Mateer, it only removes actions from the QMenuBar and doesn't delete them.

Also, deleting the list of actions from the QMenuBar will not cause each QMenu itself to be deleted.

Each QMenu that you have is parented to this which is presumably your QMainWindow . They will only be deleted when you delete the QMainWindow and not it's menu bar. You can change your code so that you parent each QMenu to the QMenuBar so that deleting the menu bar deletes the menus (and their actions). Alternatively you can keep hold of pointers to each individual menu and delete them manually.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM