4

考虑我有具有以下项目层次结构的 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()

我的错误是什么?

4

3 回答 3

1

我已经通过 Qt 文档识别出QWidget实际上并没有链接到QTreeWidgetItem:两种方法QTreeWidget::setItemWidgetQTreeWidget::itemWidget有评论

注意:树拥有小部件的所有权。

就我而言(在其他父母和孩子之间插入孩子),我实施了下一个解决方案:

  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));
  }
}
于 2014-09-30T14:47:00.073 回答
1

做同样事情的另一种方法:

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)));
}
于 2014-09-20T10:58:05.373 回答
0
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);
   }
}
于 2014-09-19T09:34:51.257 回答