Я хотел бы иметь только один экземпляр 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». Таким образом, второй кут печатает «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?
Просто взгляните на реализацию addSeparator
:
QAction *QToolBar::addSeparator()
{
QAction *action = new QAction(this);
action->setSeparator(true);
addAction(action);
return action;
}
Это создает нового ребенка QAction
и добавляет его в список действий виджета. clear
очищает список действий, но не уничтожает действия! Следовательно, они все еще будут как дети на панели инструментов.
Qt не знает, что вы не используете эти действия в другом месте — они предназначены для использования в нескольких виджетах. Если вы хотите восстановить эту память, удалите действие, возвращаемое addSeparator
,
Других решений пока нет …