Право собственности на QAction в QMenu - PullRequest
4 голосов
/ 31 января 2012

Я использовал Qt для создания базового графического интерфейса для приложения, и у меня есть несколько вопросов .. Так что я создал графический интерфейс, он работает нормально, и я подумал, что я что-то проверю ..

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

Я использую QMenuBar класса QMainWindow и заполняю его QMenu, который также заполнен QAction, для которого я подключаю сработавший сигнал к нескольким слотам. Это работает нормально, но когда я вызываю clear, это должно удалить меню / элементы действий, содержащиеся в QMenuBar .. Я проверяю в диспетчере задач, и использование памяти все еще огромно .. Даже после:

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

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

Не следует ли освободить всю память, используемую QMenus и QActions?

Ответы [ 2 ]

5 голосов
/ 31 января 2012

Нет, они все еще существуют в памяти, потому что они будут удалены только при удалении меню и меню только при этом (при условии 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();
}
4 голосов
/ 31 января 2012

QMenuBar::clear ничего не сделает для вас, поскольку, как указал @Dave Mateer, он удаляет только действия из QMenuBar и не удаляет их.

Также, удаляя список действийиз QMenuBar не приведет к удалению каждого самого QMenu.

Каждый ваш QMenu, связанный с this, который предположительно является вашим QMainWindow.Они будут удалены только при удалении QMainWindow и , а не его строки меню.Вы можете изменить свой код так, чтобы каждый родительский элемент QMenu был родительским QMenuBar, так что удаление строки меню удаляет меню (и их действия).В качестве альтернативы вы можете удерживать указатели на каждом отдельном меню и удалять их вручную.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...