2016-11-03 3 views
1

J'ai:Preserve dans les sous-classes QStandardItem glisser-déposer

self.treeView = QTreeView() 
self.treeView.setObjectName("testView") 
self.treeView.setDragDropMode(QAbstractItemView.InternalMove) 
self.treeView.setSelectionMode(QAbstractItemView.ExtendedSelection) 

itemA = SubclassQStandardItemA(self) 
itemB = SubcalssQStandardItemB(self) 

self.model = QStandardItemModel() 
self.treeView.setModel(self.model) 

self.model.appendRow(itemA) 
self.model.appendRow(itemB) 

Quand je elementB passer à elementA et vérifier sa catégorie, elementB n'est plus SubclassQStandardItemB mais QStandardItem.

Comment puis-je conserver la classe d'origine de l'élément lorsque je fais glisser et déposer?

+0

@ekhumoro Merci pour la solution! La solution dans votre lien fonctionne mais seulement si j'ai 1 classe personnalisée. Comment puis-je travailler avec 2 classes personnalisées? SubclassQStandardItemA & SubclassQStandardItemB – Dariusz

+0

Dans ce cas, vous devrez adopter une approche différente - voir ma réponse pour une possibilité. – ekhumoro

Répondre

1

Comme expliqué dans this answer, vous pouvez utiliser setItemPrototype pour fournir une fabrique d'éléments pour un modèle. Toutefois, comme indiqué également dans la réponse, seuls certains types d'informations sont transférés lors d'une opération de glisser-déposer. Pour QStandardItem, cela signifie uniquement les item flags et item data. Il n'y a aucun moyen de préserver la sous-classe spécifique de l'élément si plusieurs sous-classes sont utilisées. Un modèle ne peut avoir qu'un seul prototype, et cela est utilisé pour tous les éléments créés en interne par Qt. Cela signifie que vous ne devez pas utiliser plusieurs sous-classes QStandardItem si vous devez distinguer les différents types d'éléments. Au lieu de cela, vous devez utiliser une sous-classe unique et réimplémenter QStandardItem.type de les distinguer:

class MyItem(QtGui.QStandardItem): 
    TypeItemA = QtGui.QStandardItem.UserType 
    TypeItemB = QtGui.QStandardItem.UserType + 1 
    TypeItemC = QtGui.QStandardItem.UserType + 2 

    def clone(self): 
     return MyItem() 

    def type(self): 
     return self.data(QtCore.Qt.UserRole + 1000) 

    def setType(self, value): 
     self.setData(QtCore.Qt.UserRole + 1000, value) 

... 

itemA = MyItem(self) 
itemA.setType(MyItem.TypeItemA) 
itemB = MyItem(self) 
itemB.setType(MyItem.TypeItemB) 
+0

J'ai essayé ce code, j'ai eu une erreur. AttributeError: l'objet type 'QStandardItem' n'a pas d'attribut 'UserData' Puis j'ai remplacé UserData par UserType, cela a fonctionné dans certains cas mais je suis toujours perplexe ... Si je devais configurer dans __init__ self.userCustomStuff = quelque chose, et ensuite Je voudrais apporter cela à un nouvel élément droped ... est-ce que j'utilise type/setType? ou j'ai besoin de données/setData? Connaissez-vous un palce qui l'explique peut-être en pyqt/pyside? – Dariusz

+1

@Dariusz. J'ai corrigé l'exemple de code. Comme je l'ai expliqué dans ma réponse, seuls les drapeaux d'article et les données d'article sont transférés dans un glisser-déposer. Tout le reste est complètement ignoré. Vous devez donc utiliser 'setData' avec un rôle personnalisé pour les données utilisateur personnalisées (ce qui est exactement la façon dont' type' fonctionne dans mon exemple). Si vous voulez des attributs de type python, vous pouvez implémenter cela avec [@property] (http://docs.python.org/3/library/functions.html#property). – ekhumoro

+0

Je voulais juste vous faire savoir que seulement maintenant (quand j'ai commencé à faire C++ Qt) après (presque) une année, je comprends maintenant vraiment bien ce que vous voulez dire et je l'aime lol. Merci! – Dariusz