Question

Bonjour,

J'ai écrit un code méchant pour soutenir l'undo / redo de suppression d'un ensemble arbitraire d'objets de mon modèle. Je sens que je vais sur ce bien, comme tous les autres mutators (ajout / du copier-coller) sont des sous-ensembles de cette fonctionnalité.

Le code est plus méchant qu'il a besoin de moi, surtout parce que la seule façon de muter le modèle implique d'appeler beginInsertRows / beginRemoveRows et en supprimant les lignes d'une plage (juste faire 1 ligne à la fois, pas besoin d'optimiser les « voisins » en un seul appel encore)

Le problème avec beginInsertRows / beginRemoveRows est que la suppression d'une ligne pourrait affecter un autre QModelIndex (par exemple, l'un dans une liste en cache). Par exemple:

ParentObj
   ->ChildObj1
   ->ChildObj2
   ->ChildObj3

Dire que je choisis ChildObj1 et ChildObj3 et les supprimer, si je retire ChildObj1 d'abord j'ai changé QModelIndex de ChildObj3 (ligne est maintenant différente). Des problèmes similaires se produisent si je supprime un objet parent (mais je l'ai résolu par cette « taille » les enfants de la liste des objets).

Voici les moyens que j'ai pensé de contourner cette limitation de l'interface, mais je pensais que je demande un meilleur avant d'aller de l'avant:

  1. Déplacer « en arrière », en supposant une liste fournie de QModelIndices est orderered de haut en bas juste aller de bas en haut. Cela nécessite vraiment de tri pour être fiable, et le genre serait probablement quelque chose naïf et lent (peut-être il y a une façon intelligente de trier une collection de QModelIndexes? Ou est-QItemSelectionModel fournir des listes de bons (commandés)?)

  2. Mise à jour d'autres QModelIndeces chaque fois qu'un objet est supprimé / ajouté (ne peut pas penser à une solution non naïve, consulter la liste, obtenir de nouveaux QModelIndeces si nécessaire)

  3. Depuis la mise à jour des données réelles est facile, il suffit de mettre à jour les données et reconstruire le modèle. Cela semble grotesque, et je peux l'imaginer obtenir assez lent avec de grands ensembles de données.

Ce sont les idées que j'ai actuellement. Je travaille sur l'option 1 en ce moment.

Cordialement, Dan O

Était-ce utile?

La solution

Pensez à beginRemoveRows / endRemoveRows, etc. comme des méthodes pour demander à la classe de base QAbstractItemModel pour fixer vos index modèles persistants pour vous au lieu de juste une façon de vue la mise à jour, et essayer de ne pas confondre la classe de base QAbstractItemModel dans ses travaux sur ces indices. Consultez http://labs.trolltech.com/page/Projects/Itemview/Modeltest pour exercer votre modèle et si vous gardez la classe de base de QAbstractItemModel heureux.

Si QPersistentModelIndex ne permet pas est si vous voulez garder votre undo / redo des données en dehors du modèle. J'ai construit un modèle qui est fortement modifié, et je ne voulais pas essayer de tout garder dans le modèle. Je stocke les données undo / redo sur la pile d'annulation. Le problème est que si vous modifiez une colonne, le stockage de l'indice persistant de cette colonne sur la pile undo, puis supprimez la ligne contenant cette colonne, l'index persistant de la colonne devient invalide.

Ce que je fais est de garder à la fois un index de modèle persistant, et un QModelIndex régulier « historique ». Quand il est temps de défaire / refaire, je vérifie si l'index persistant est devenu invalide. Si elle a, je passe le QModelIndex historique à une méthode particulière de mon modèle pour lui demander de recréer l'index, en fonction de la ligne, colonne et internalPointer. Étant donné que toutes mes modifications sont sur la pile undo, le temps que j'ai sauvegardé à cette modification de la colonne sur la pile undo, la ligne est sûr d'être là dans le modèle. Je garde l'état assez dans le internalPointer pour recréer l'index d'origine.

Autres conseils

J'envisager d'utiliser un modèle « tout-données » et un modèle proxy filtre avec le modèle de données. Les données ne sera ajoutée au modèle tout-données, et jamais supprimée. De cette façon, vous pouvez stocker votre undo / redo avec des références à ce modèle. (Puis-je suggérer QPersistentModelIndex?). Votre modèle de données pourrait aussi suivre ce qui doit être montré, en quelque sorte. Le modèle de filtre alors renvoie l'information pour les éléments qui doivent être présentés à un moment donné.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top