2010-04-15 14 views
1

J'écris un programme de test simple en utilisant QTreeModel et QTreeView pour un projet plus complexe plus tard. Dans ce programme simple, j'ai des données dans des groupes qui peuvent être contractés ou développés, comme on pourrait s'y attendre dans un QTreeView. Les données peuvent également être triées par les différentes colonnes de données (QTreeView.setSortingEnabled est True). Chaque élément de l'arborescence est une liste de données, de sorte que la fonction de tri mis en œuvre dans la classe TreeModel utilise la liste python intégré tri:PyQt: Comment garder les nœuds QTreeView correctement développés après un tri

self.layoutAboutToBeChanged.emit() 
self.rootItem.childItems.sort(key=lambda x: x.itemData[col], reverse=order) 
for item in self.rootItem.childItems: 
    item.childItems.sort(key=lambda x: x.itemData[col], reverse=order) 
self.layoutChanged.emit() 

Le problème est que chaque fois que je change le tri des éléments enfants de la racine (l'arbre n'a que 2 niveaux de profondeur, donc c'est le seul niveau avec les enfants) les nœuds ne sont pas nécessairement développés comme avant. Si je change le tri sans développer ou réduire quoi que ce soit, les nœuds sont développés comme avant le changement de tri.
Quelqu'un peut-il m'expliquer ce que je fais mal? Je suppose que c'est quelque chose avec la réaffectation de QModelIndex avec les nœuds triés, mais je ne suis pas sûr.

Répondre

1

J'ai résolu le problème en implémentant un QSortFilterProxyModel pour le tri.

+0

Serait bien de voir un SSCCE dans la question initiale, et une implémentation de la solution dans la réponse. Ce n'est pas trop tard! – neuronet

2

Pour répondre à votre question "ce que je fais de mal" - vous n'avez pas mis à jour les index de modèles persistants avant d'émettre layoutChanged(). Les clients de votre modèle ne savent pas par magie comment les données de votre modèle ont évolué; par exemple, ils ne savent pas que l'index (2,0, racine) s'est déplacé pour devenir (12,0, racine).

La façon dont vous communiquez le changement consiste à émettre les signaux de mise en page; vous avez cette partie correcte. Qt répond très probablement à layoutAboutToBeChanged() en convertissant tout QModelIndex qu'il conserve en QPersistentModelIndex. Quand il reçoit layoutChanged(), il les reconvertit. Entre les deux, vous êtes supposé parcourir cette liste QPersistentModelIndex et mettre à jour les index avec de nouveaux emplacements. Vérifiez les documents pour le signal layoutChanged().