Я у себя так вот сделал, для двухуровневого дерева
// Реализация выбора элементов в дереве зависимостей
void MainWindow::on_treeWidget_itemChanged(QTreeWidgetItem* item, int column)
{
// Блокируем сигналы дерева зависимостей (treeWidget),
// дабы избежать рекурсии при ручном управлении состоянием элементов.
ui->treeWidget->blockSignals(true);
// Изменяем состояние дочерних элементов
const int childCount = item->childCount();
for (int i = 0; i < childCount; i++)
item->child(i)->setCheckState(column, item->checkState(column));
// Установка статусов Qt::Checked, Qt::Unchecked, Qt::PartiallyChecked
QTreeWidgetItem* root = item->parent();
if (root && (root != item)) {
const int childCount = root->childCount();
int checkedCount = 0;
// Считаем общее к-во элементов с установленным статусом - Qt::Checked
for (int i = 0; i < childCount; i++)
if (root->child(i)->checkState(column) == Qt::Checked)
++checkedCount;
// В зависимости от checkedCount,
// устанавливаем статус главному элементу.
if (checkedCount == childCount)
root->setCheckState(column, Qt::Checked);
else if (checkedCount == 0)
root->setCheckState(column, Qt::Unchecked);
else
root->setCheckState(column, Qt::PartiallyChecked);
}
ui->treeWidget->blockSignals(false);
}