2017-01-07 5 views
1

Utilisation de PyQt 5 J'ai essayé de trouver un moyen de faire glisser et déposer l'ancien parent sur un élément dans une situation QTreeView en utilisant QStandardItemModel et QStandarItems.PyQt 5 QStandardItem Enregistrement de l'ancien parent

Je veux vraiment éviter de créer mon propre modèle si possible. Ma tentative actuelle consiste à stocker le parent actuel dans l'élément lorsqu'il est créé en tant que "parent ancien" et il ne doit pas être mis à jour dans le déplacement afin que je puisse le référencer mettre à jour les valeurs dans les anciens éléments parents, puis mettre à jour le "vieux parent" dans l'élément déplacé vers le nouveau parent actuel.

Je ne peux pas sembler le faire fonctionner bien, voici le code que je suis en train d'utiliser pour stocker le « vieux parent » lorsque l'élément est créé:

item.setData(parent.index(),(Qt.UserRole+3)) 

Quand je lance ce mais je l'erreur suivante:

QVariant::save: unable to save type 'QModelIndex' (type id: 42).

et je ne peux pas faire référence à l'ancien parent à ce moment ...

J'ai trouvé une référence en utilisant C++ et beaucoup de « casting pointeur », mais je ne pouvais pas comment convertir le code à Python et PyQt 5.

C++ Référence: https://forum.qt.io/topic/1690/qvariant-save-load-unable-to-save-type-x/19

Merci pour toute aide!

+0

Avec votre tentative actuelle, dès que vous glissez-déposez un élément, les index stockés de tous ses enfants (et tous leurs enfants, etc.) seront immédiatement invalidé. Donc, ce type d'approche ne va pas fonctionner, peu importe comment il est mis en œuvre. Quel est le problème que vous essayez de résoudre en faisant cela? – ekhumoro

+0

J'essaye de mettre à jour la somme d'une colonne quand j'enlève une rangée d'articles et la dépose à un autre endroit dans l'arbre. Chaque nœud parent a un élément de somme qui conserve une somme des éléments enfants dans la colonne, j'essaie d'obtenir cet élément de somme à mettre à jour chaque fois que je déplace des éléments dans et hors. J'espère que cela a du sens! – Zexelon

Répondre

0

Le modèle a some signals que le feu chaque fois sont insérés ou enlevés les enfants d'un élément, alors ceux-ci pourraient être utilisés pour mettre à jour automatiquement l'élément.

Après quelques essais, je trouve que les signaux doivent être utilisés avec un queued connection, de sorte que le modèle a une chance de mise à jour complète:

model.rowsInserted.connect(slot, type=QtCore.Qt.QueuedConnection) 
model.rowsRemoved.connect(slot, type=QtCore.Qt.QueuedConnection) 

Mais autre que cela, la mise en œuvre est assez simple. Il n'est pas nécessaire de stocker des informations supplémentaires dans les éléments, car les mises à jour peuvent être effectuées dynamiquement.

Voici un script de démonstration de base:

from PyQt5 import QtCore, QtGui, QtWidgets 

class Window(QtWidgets.QTreeView): 
    def __init__(self): 
     super(Window, self).__init__() 
     self.setDragDropMode(QtWidgets.QAbstractItemView.InternalMove) 
     self.setDragDropOverwriteMode(False) 
     self.header().hide() 
     model = QtGui.QStandardItemModel(self) 
     model.rowsInserted.connect(
      self.sumItems, type=QtCore.Qt.QueuedConnection) 
     model.rowsRemoved.connect(
      self.sumItems, type=QtCore.Qt.QueuedConnection) 
     self.setModel(model) 
     parent = model.invisibleRootItem() 
     for index in range(3): 
      item = QtGui.QStandardItem('0') 
      parent.appendRow(item) 
      for row in range(1, 5): 
       child = QtGui.QStandardItem(str(row)) 
       item.appendRow(child) 
     self.expandAll() 

    def sumItems(self, index, first, last): 
     if index.isValid(): 
      total = 0 
      parent = self.model().itemFromIndex(index) 
      for row in range(parent.rowCount()): 
       child = parent.child(row) 
       if child is not None: 
        total += int(child.text()) 
      parent.setText(str(total)) 

if __name__ == '__main__': 

    import sys 
    app = QtWidgets.QApplication(sys.argv) 
    window = Window() 
    window.setGeometry(700, 100, 250, 300) 
    window.show() 
    sys.exit(app.exec_()) 
+0

C'est exactement ce que je cherchais! J'ai complètement raté les documents WRT rowsInserted et rowsRemoved. Par exemple, le rowCount dans un modèle ne sont pas modifiés en ajoutant des enfants à des éléments (en utilisant le item.appendRow()) mais ces signaux sont toujours envoyés ... – Zexelon