Странное поведение 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;} , то всё работает нормально. Кто-нибудь знает причину этого загадочного явления? |
|
|
chereppiter |
19.12.2012, 11:00
Сообщение
#2
|
Студент Группа: Участник Сообщений: 30 Регистрация: 12.11.2012 Пользователь №: 3595 Спасибо сказали: 0 раз(а) Репутация: 0 |
1) Чтобы было более понятно, приведу полный текст функций, строящих дерево:
void SelCameraDialog::buildTree() { tree->clear();} void SelCameraDialog::addChilds(QTreeWidgetItem* item, int id) { QTreeWidgetItem* child; } В buildTree в дерево добавляются корневые узлы, не имеющие родителя (т.е. у которых parentid==0). Далее вызывается метод addChilds(item, id) для рекурсивного добавления дочерних элементов к узлу item. id в теле item нету, т.к. item содержит только название узла. У узла может быть 2 типа дочерних элементов: другой узел или камера. И то, и то - по сути просто структуры, имеющие в качестве основных полей идентификатор (id), идентификатор родительского узла (parentid) и название (name). Отличие только в том, что узел может иметь детей, а камера - нет. 2) nodes - это стандартный вектор структур: struct NodeParams { int id; }; Заполняется заранее инфой, распарсенной из xml-ки. cameras - аналогичный вектор. 3) Ребёнка в любом случае приходится сначала создать, чтобы было к чему подцеплять потомков, если таковые есть. Соответственно, если потомков нет, его приходится удалять. К дереву его, конечно, можно подцеплять только в том случае, если потомки есть, но это в данном случае не принципиально. На самом деле интересен сам факт такого странного поведения removeChild. Что вообще по идее делает этот метод? Мне кажется, что он должен просто удалять указатель на объект QTreeWidgetItem из списка дочерних элементов. А тут получается, что я создал 2 разных объекта QTreeWidgetItem, прицепил указатели на них к родительскому QTreeWidgetItem, потом вызовом removeChild удалил указатель на один из них из списка дочерних элементов родительского QTreeWidgetItem, после чего этот список оказался пуст, хотя должен был содержать 1 элемент. Выглядит как-то нелогично Выше приведённый код работает правильно, неправильно работал такой фрагмент addChilds: if (nodes[i].parentid == id) { child = new QTreeWidgetItem(item); } |
|
|
Текстовая версия | Сейчас: 25.11.2024, 10:34 |