2016-02-04 2 views
0

Я хотел бы иметь только один экземпляр QToolBar и изменять его много раз во время выполнения моего приложения. Тем не менее, меня беспокоит управление памятью, выполненное Qt.Список детей 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! 

Изначально список детей имеет размер 3. Затем я называю «addSeparator» и два парня будут добавлены в этот список. Хорошо, я могу жить с этим. Однако после вызова «очистить» эти ребята не удаляются. Для каждого вызова «addSeparator» или «addWidget» добавляются двое детей, и они никогда не удаляются.

Я использую Qt 5.4.1 для MSVC 2013, Windows.


Редактировать: добавление кода, предложенного peppe. Пожалуйста, прочитайте комментарии к строке.

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? 

ответ

2

Просто взгляните на реализацию addSeparator:

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

Это создает новый дочерний QAction и добавляет его в список действий виджета. clear очищает список действий, но не уничтожает действия! Следовательно, они все равно будут находиться как дети панели инструментов.

Qt не знает, что вы не используете эти действия в другом месте - они предназначены для использования в нескольких виджетах. Если вы хотите восстановить эту память, удалите действие, возвращенное addSeparator.

+0

Предположим, что размер детского списка инструментов - x. Затем я вызываю 'toolBar.addSeparator()' много раз. После этого я повторяю список, возвращаемый 'toolBar.actions()', и удаляю каждый указатель в этом списке. Размер списка дочерних элементов панели инструментов должен быть снова x? Боюсь, этого не происходит. –

+0

Можете ли вы изменить свой вопрос, показывая код, через который вы это делаете? – peppe

+0

Готово. Теперь вместо вызова 'toolBar.clear();' я повторяю список действий и удаляю каждое действие. Пожалуйста, прочитайте комментарии к строке. –

 Смежные вопросы

  • Нет связанных вопросов^_^