Представьте, что у меня есть 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()
,
В чем моя ошибка?
Еще один способ сделать то же самое:
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)));
}
Я признал документацию Qt, что QWidget
на самом деле не связан с QTreeWidgetItem
: оба метода QTreeWidget::setItemWidget
а также QTreeWidget::itemWidget
есть комментарий
Примечание. Дерево становится владельцем виджета.
В моем случае (вставьте child между другими parent и child) я реализовал следующее решение:
get_copy()
метод для моего виджетаQTreeWidget
копирование связанных виджетов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));
}
}
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);
}
}