如何在Qt中迭代QTreeWidgetItem的子项

3

Qt提供QTreeWidgetItemIterator类来迭代树形视图的项目。甚至有一个构造函数版本,它会接受项目指针而不是视图。不幸的是,即使在这种情况下,迭代也将一直进行到最后一个项目,通常这不是期望的行为。如果我从项目开始,我只想迭代它的子代和孙代。当然,我可以再循环一次来检查是否超出了起始项目,但那很丑陋。有没有更好的方法?

 QTreeWidgetItemIterator it(treeWidget);
        while (*it) {
            if ((*it)->text(0) == itemText)
                (*it)->setSelected(true);
            ++it;
        }
3个回答

3
如果您有父项作为起点,那么只需循环遍历其子项即可:
for (int i = 0; i < item->childCount (); i++)
{
    QTreeWidgetItem *child = item->child (i);
    // ... perform work here ...
}

我没有看到可以循环遍历一个元素的子元素的迭代器,但其实并不需要。

因为item->child(i)需要额外的O(n)循环,这样做会不会太慢了? - def

0

这是一个有点老的问题,但我刚刚偶然发现。@goug的答案非常正确,并且没有任何额外开销(O(n)实际上是你可以访问N个元素的最小值,相当于迭代器解决方案)。但如果你不喜欢行索引(就像我一样),QTreeWidgetItemIterrator支持各种过滤器,所以在大多数情况下,我只需要编写类似以下代码即可:

QTreeWidget * tree;
QTreeWidgetItemIterator it(tree,QTreeWidgetItemIterator::HasChildren);

但是根据您提供的确切描述,我不认为过滤器是可行的,所以我会这样做

QTreeWidgetItemIterator it(treeWidget);
        while (*it) {
            while ((*it)->parent() && (*it)->parent()->parent()
                &&(*it)->parent()->parent()->parent())
                ++it; //while item has grand-grandparent skip it 
            //do things
            ++it;
        }


QTreeWidgetItem::child()并没有像其他人指出的那样有额外的循环,但它确实会导致一些减速,因为它调用executePendingSort()。如果您在迭代时编辑树,每次调用child()都会触发排序。请参见qtreewidget.h - Sergio Monteleone

0
一个完整的例子:
QObject::connect(ui.treeWidget_2, SIGNAL(itemChanged(QTreeWidgetItem*, int)), this, SLOT(treeWidget2_itemClickedButtonAction(QTreeWidgetItem*)));

void treeWidget2_itemClickedButtonAction(QTreeWidgetItem* item)
{
    Qt::CheckState state = item->checkState(0);
    setChildState(item, state);
}

void setChildState(QTreeWidgetItem* item, Qt::CheckState state) {
    for (int i = 0; i < item->childCount(); i++)
    {
        QTreeWidgetItem* child = item->child(i);
        child->setCheckState(0, state);
        if (child->childCount() > 0)
            setChildState(child, state);
    }
}

这不是被问的内容吗?子代的问题呢? - def

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接