QTreeWidget —— 复选框QCheckBox联动

QTreeWidget构建

void Widget::InitAvaliableBlood()
{
    // 可用血管

    QStringList listblood = {"childnode1", "childnode2"};

    QStandardItemModel *model = new QStandardItemModel();
    QStandardItem *item = new QStandardItem(QString("node"));
    item->setCheckable(true); 
    item->setTristate(true);  // 三种状态的复选框
    for (int i=0; i<listblood.count(); i++){
        QStandardItem *itemchild = new QStandardItem(listblood.at(i));
        itemchild->setCheckable(true);
        item->appendRow(itemchild);  // 连接子节点
    }
    model->appendRow(item);
    connect(model, &QStandardItemModel::itemChanged, this, &SpasmTrendWidget::OnItemChanged);
    ui->treeView_blood->setModel(model);
    ui->treeView_blood->setHeaderHidden(true);  // 隐藏横向表头
    ui->treeView_blood->expandAll();  // 默认展开

}

复选框联动

void Widget::OnItemChanged(QStandardItem *item)
{
    if (item == nullptr)
    {
        return;
    }
    if (item -> isCheckable())
    {
        Qt::CheckState state = item->checkState();  // 当前变化的节点

        if (state == Qt::PartiallyChecked)  // 由于子节点变化才可能导致partiallychecked
        {
            return;
        }

        // 全选 & 全不选
        ChangeChildItemState(item, state);  // 变更子节点状态
        item->setCheckState(state);
        ChangeParentItemState(item);  // 变更父节点状态
    }
}

// 子节点状态改变
void Widget::ChangeChildItemState(QStandardItem *item, Qt::CheckState check)
{
    if (item == nullptr)
    {
        return;
    }

    // 遍历子节点
    int ichildnumber = item->rowCount();
    for (int ichild = 0; ichild < ichildnumber; ichild++){
        QStandardItem *itemchild = item->child(ichild);
        ChangeChildItemState(itemchild, check);  // 在setcheckstate之前递归,因为setcheckstate会触发信号
        if (itemchild->checkState() != check){  // 控制不需要改变的复选框,不触发信号,直接返回
            itemchild->setCheckState(check);
        }
    }
}

void Widget::ChangeParentItemState(QStandardItem *item)
{
    // 父节点状态
    if (item->parent() == nullptr){
        return;
    }
    QStandardItem *itemparent = item->parent();
    int iparentchild = itemparent->rowCount();
    int icheckednumber = 0;
    for (int ibrother = 0; ibrother < iparentchild; ibrother++)  // 兄弟节点
    {
        Qt::CheckState statebrother = itemparent->child(ibrother)->checkState();
        if (statebrother == Qt::Checked)
        {
            icheckednumber += 2;
        }
        else if(statebrother == Qt::PartiallyChecked)
        {
            icheckednumber ++;
        }
    }

    Qt::CheckState stateparent;
    if (icheckednumber == 2*iparentchild)
    {
        stateparent = Qt::Checked;
    }
    else if (icheckednumber == 0)
    {
        stateparent = Qt::Unchecked;
    }
    else{
        stateparent = Qt::PartiallyChecked;
    }
    if (itemparent->checkState() != stateparent){
        itemparent->setCheckState(stateparent);
        ChangeParentItemState(itemparent);  // 递归在setcheckstate后,由于需要用到当前itemparent的状态,来看itemparent->parent()的状态是否改变
    }
}

Problem: QTreeWidget不随界面自适应高度

解决方案:将QTreeWidget的垂直sizePolicy设为ignore.

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值