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.