![]() |
Здравствуйте, гость ( Вход | Регистрация )
![]() |
chereppiter |
![]()
Сообщение
#1
|
Студент ![]() Группа: Участник Сообщений: 30 Регистрация: 12.11.2012 Пользователь №: 3595 Спасибо сказали: 0 раз(а) Репутация: ![]() ![]() ![]() |
Есть функция построения дерева (QTreeWidget), в которой для каждого элемента верхнего уровня рекурсивно вызывается функция добавления отпрысков:
void addChilds(QTreeWidgetItem* item, int id) По возвращению из рекурсивной addChilds, если у текущего чаилда детей нет, то он удаляется. Ситуация такая: на одной из итераций цикла к item был добавлен child (и не был удалён, т.к. у него тоже есть дети). На одной из последующих итераций создаётся child, для которого потом childCount оказывается 0, поэтому он удаляется (item->removeChild(child)). При этом почему-то вместе с этим отпрыском удаляется и тот, который был добавлен на одной из предыдущих итераций. Проблема решается исключением из вышеприведённого кода строчки: item->removeChild(child); Т.е. если удаление выглядит так: if (!child->childCount()) { delete child;} , то всё работает нормально. Кто-нибудь знает причину этого загадочного явления? |
|
|
![]() |
chereppiter |
![]()
Сообщение
#2
|
Студент ![]() Группа: Участник Сообщений: 30 Регистрация: 12.11.2012 Пользователь №: 3595 Спасибо сказали: 0 раз(а) Репутация: ![]() ![]() ![]() |
Не понимаю, в чём неправильность моего подхода к дереву. Строится оно вполне логично и правильно, если не использовать removeChild. Зачем мне дополнительная прослойка в виде stl-ного словаря, если мне это дерево нужно только для того, чтобы его отобразить в виджете и больше ни для чего? Моя ошибка, скорее всего, в том, что я не совсем правильно понимаю назначение метода removeChild. Я-то предположил, что он работает в соответствии со своим названием, т.е. удаляет потомка, указатель на который передан в аргументе, ан-нет! Я смотрел и в отладчике, и логи: удаляется 2 потомка с разными указателями - тот, который нужно удалить, и тот, который был добавлен когда-то ранее. Это подтверждается и тем, что при delete child всё работает как надо. Т.е. подробно по шагам: в функции addChilds у меня есть указатель на текущий элемент item, к которому ранее был добавлен потомок, что я проверяю вызовом item->childCount(), который возвращает 1. Далее создаю child = new QTreeWidgetItem(item), опять вызываю item->childCount() - получаю 2; вызываю addChilds(child, child_id), после возврата имею child->childCount() == 0, вызываю для проверки item->childCount() - всё правильно, он до сих пор равен 2-м; теперь вызываю item->removeChild(child), после чего опять проверяю item->childCount() - теперь он уже равен 0. Т.е. каким-то образом после вызова item->removeChild(child) у item удалились все потомки. При простой замене item->removeChild(child) на delete child всё начинает работать правильно! Отсюда вывод: removeChild работает не так, как я от него ожидаю. Возникает вопрос: как он работает?
![]() ![]() ![]() |
|
|
![]() ![]() ![]() |
![]() |
Текстовая версия | Сейчас: 18.2.2025, 5:58 |