Как вставить дочерний элемент в иерархию QTreeWidget?

Представьте, что у меня есть QTreeWidget со следующей иерархией элементов:

top_item
|--child

Каждый пункт назначен с setItemWidget() виджет.
Мне нужно вставить еще одного ребенка между моими первыми двумя элементами, как это:

top_item
|--another_child
|--child

Я пытаюсь сделать это с помощью следующего кода:

QTreeWidgetItem* top_item = new QTreeWidgetItem;
ui->treeWidget->addTopLevelItem(top_item);
QTreeWidgetItem* child_item = new QTreeWidgetItem;
top_item->addChild(child_item);

ui->treeWidget->setItemWidget(top_item, 0, new QPushButton);
ui->treeWidget->setItemWidget(child_item, 0, new QPushButton);

// ---- let's insert another child ----
auto last_children = top_item->takeChildren();

QTreeWidgetItem* another_child_item = new QTreeWidgetItem;
top_item->insertChild(0, another_child_item);
ui->treeWidget->setItemWidget(another_child_item, 0, new QPushButton);

another_child_item->addChildren(last_children);

Он отлично работает, кроме одного момента — он потерял назначенные виджеты.
Я пытался взять и сохранить виджеты, прежде чем брать детей с

QWidget* widget_from_child_item = ui->treeWidget->itemWidget(child_item, 0);
ui->treeWidget->removeItemWidget(child_item, 0);

но после звонка takeChildren() все назначенные виджеты были удалены, и приложение перестало работать после переназначения виджетов с setItemWidget(),

В чем моя ошибка?

2

Решение

Еще один способ сделать то же самое:

QTreeWidgetItem *child = ui->treeWidget->currentItem();
QTreeWidgetItem *parent = child->parent();

if(parent)
{
QTreeWidgetItem *another_child = new QTreeWidgetItem();
another_child->setText(0,"another_child");
parent->addChild(another_child);
another_child->addChild(parent->takeChild(parent->indexOfChild(child)));
}
1

Другие решения

Я признал документацию Qt, что QWidget на самом деле не связан с QTreeWidgetItem: оба метода QTreeWidget::setItemWidget а также QTreeWidget::itemWidget есть комментарий

Примечание. Дерево становится владельцем виджета.

В моем случае (вставьте child между другими parent и child) я реализовал следующее решение:

  1. Воплощать в жизнь get_copy() метод для моего виджета
  2. Перед тем как забрать товар из QTreeWidget копирование связанных виджетов
  3. После вставки нового элемента и перемещения старого элемента назначьте скопированные виджеты соответствующим QTreeWidgetItem

Вот небольшой пример:

void insert_tree_item(i_tree_item* new_widget_item)
{
QTreeWidgetItem* current_item = _tree_widget->currentItem();

if(current_item->childCount())
{
QList<QWidget*> widgets;
widgets.push_front(dynamic_cast<QWidget*>(new_widget_item));
QTreeWidgetItem* ptr = current_item->child(0);
while(ptr != nullptr)
{
QWidget* widget = _tree_widget->itemWidget(ptr, 0);
widgets.push_back(dynamic_cast<i_tree_item*>(widget)->get_copy());
auto prev_ptr = ptr;
ptr = ptr->child(0);
if(ptr == nullptr)
{
prev_ptr->addChild(new QTreeWidgetItem);
}
}
ptr = current_item->child(0);
while(widgets.count() != 0)
{
_tree_widget->setItemWidget(ptr, 0, widgets.takeFirst());
ptr = ptr->child(0);
}
}
else
{
QTreeWidgetItem* new_item = new QTreeWidgetItem;
current_item->addChild(new_item);
_tree_widget->setItemWidget(new_item, 0, dynamic_cast<QWidget*>(new_widget_item));
}
}
1

void insertAParent() {
if (tree->selectedItems().count() != 1)
return;

QTreeWidgetItem *item = tree->selectedItems().front();
QTreeWidgetItem *oldParent = item->parent();
if (oldParent) {
int index = oldParent->indexOfChild(item);
item = oldParent->takeChild(index);
QTreeWidgetItem *newParent = new QTreeWidgetItem;
newParent->setText(0, tr("Something"));
oldParent->insertChild(index, newParent);
newParent->insertChild(0, item);
}
}
0
По вопросам рекламы [email protected]