Странное поведение QTreeWidgetItem::removeChild |
Здравствуйте, гость ( Вход | Регистрация )
Странное поведение QTreeWidgetItem::removeChild |
chereppiter |
18.12.2012, 10:56
Сообщение
#1
|
Студент Группа: Участник Сообщений: 30 Регистрация: 12.11.2012 Пользователь №: 3595 Спасибо сказали: 0 раз(а) Репутация: 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;} , то всё работает нормально. Кто-нибудь знает причину этого загадочного явления? |
|
|
Алексей1153 |
19.12.2012, 14:37
Сообщение
#2
|
фрилансер Группа: Участник Сообщений: 2941 Регистрация: 19.6.2010 Из: Обливион Пользователь №: 1822 Спасибо сказали: 215 раз(а) Репутация: 34 |
chereppiter, что делает этот метод, можно прочитать в доке
Цитата void QTreeWidgetItem::removeChild ( QTreeWidgetItem * child ) Removes the given item indicated by child. The removed item will not be deleted. метод работает так, как ему и положено, ошибка где-то у тебя. Неправилен сам подход к дереву, поэтому появляется дополнительная возможность ошибки - а где она, это без отладчика так сразу я не вижу, конечно. Сделай минимального размера дерева, где ошибка появляется , затем отладчиком прошагай рекурсию, обращая внимания на адреса элементов и момент, когда удалился не тот элемент, который ожидалось Ну и про правильный подход:
пример создания элементов дерева (легко переделать в рекурсивный вариант)
тут мы контролируем всю подноготную жизни элементов , всегда их все можем быстро найти и посмотреть. По указателю на потомка всегда найдём его родителя (m_parent) , а по мапе - всю ветку элемента. При удалении ветки следует рекурсивно пройтись по её потомкам и 1) вариант первый - удалить их из мапы (но не из кучи, так как это сделает сам QTreeWidgetItem) , затем delete корень ветки 2) вариант второй - удалить их из мапы , из всех родительских элементов и из кучи , затем delete корень ветки (первый вариант в нашем случае красивее) показать наше дерево в QTreeWidget - метод void QTreeWidget::insertTopLevelItem ( int index, QTreeWidgetItem * item ) , куда надо передать корень ну и не забывать отключать его от QTreeWidget , чтобы QTreeWidget не удалил всё сам в деструкторе, когда это нужно Попробуй Сообщение отредактировал Алексей1153 - 19.12.2012, 16:12 |
|
|
Текстовая версия | Сейчас: 29.11.2024, 2:26 |