Я у себя так вот сделал, для двухуровневого дерева 

// Реализация выбора элементов в дереве зависимостей
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);
}