3

我正在编写一个具有 QTreeWidget 的应用程序,该应用程序通过解析包含树级别的 XML 文件来填充。如果我选择一个顶级复选框,我还需要检查所有子级别的复选框。

我已经让 XML 解析器工作并使用带有复选框的 QTreeWidgetItems 填充 QTreeWidget,但它们只能单独检查。

4

3 回答 3

6

为此,请保留使用 XML 生成树的代码。然后连接到 itemChanged() 信号并更新插槽中的检查状态。它应该看起来像:

connect(treeWidget, SIGNAL(itemChanged(QTreeWidgetItem*, int)),
        this,       SLOT(updateChecks(QTreeWidgetItem*, int)));

void ClassName::updateChecks(QTreewidgetItem* item, int column)
{
    // Checkstate is stored on column 0
    if(column != 0)
        return;

    recursiveChecks(item);
}

void ClassName::recursiveChecks(QTreeWidgetItem* parent)
{
    Qt::CheckState checkState = parent->checkState(0);
    for(int i = 0; i < parent->childCount(); ++i)
    { 
       parent->child(i)->setCheckState(0, checkState);
       recursiveChecks(parent->child(i));
    }   
}

需要考虑的一些注意事项:

  1. 您可能很想使用 itemClicked 信号而不是 itemChanged 信号。这通常有效,但当用户使用箭头键和空格键更改检查状态时将无效。
  2. 您需要考虑当您取消选中已通过单击其父项选中的子项之一时会发生什么。通常这意味着您需要取消选中或部分选中所有祖先。这可能不适用于您的情况。
  3. itemUpdated 也会因项目的其他更改(如文本更改)而被触发,因此请注意,这不是一种超级有效的方法。
于 2012-02-09T00:00:11.413 回答
4

这在搜索引擎中似乎仍然很高,并且已经过时。只需在顶级项目上设置标志 Qt::ItemIsAutoTristate 即可。

于 2019-04-28T10:47:11.853 回答
3

我只是做了一点工作,并根据 Rick 的回答得到了不错的结果。也许它可以帮助其他人。它仅更新父母的三态状态(选中、未选中、部分选中)的父母和孩子的状态。

void ClassName::updateChecks(QTreeWidgetItem *item, int column)
{
    bool diff = false;
    if(column != 0 && column!=-1)
        return;
    if(item->childCount()!=0 && item->checkState(0)!=Qt::PartiallyChecked && column!=-1){
        Qt::CheckState checkState = item->checkState(0);
        for (int i = 0; i < item->childCount(); ++i) {
           item->child(i)->setCheckState(0, checkState);
        }
    } else if (item->childCount()==0 || column==-1) {
        if(item->parent()==0)
            return;
        for (int j = 0; j < item->parent()->childCount(); ++j) {
            if(j != item->parent()->indexOfChild(item) && item->checkState(0)!=item->parent()->child(j)->checkState(0)){
                diff = true;
            }
        }
        if(diff)
            item->parent()->setCheckState(0,Qt::PartiallyChecked);
        else
            item->parent()->setCheckState(0,item->checkState(0));
        if(item->parent()!=0)
            updateChecks(item->parent(),-1);
    }
}

不再需要 recursiveChecks() 了。treeWidget 和 updateChecks 之间的连接仍然处于活动状态。

于 2013-08-21T09:23:55.347 回答