2010-11-12 22 views
11

Dans PyQt 4, je voudrais créer un QTreeView avec la possibilité de réorganiser sa structure avec la manipulation de glisser-déposer.QTreeView avec support glisser-déposer dans PyQt

J'ai implémenté mon propre modèle (QAbstractItemModel) pour QTreeView afin que mon QTreeView affiche correctement les données. Maintenant, je voudrais ajouter le support glisser-déposer pour les nœuds de l'arbre pour pouvoir déplacer un nœud dans l'arbre d'un parent à l'autre, copier-coller, etc. mais je ne trouve pas de tutoriel complet pour y parvenir. J'ai trouvé quelques tutoriels et astuces pour QTreeWidget, mais pas pour QTreeView avec un modèle personnalisé. Quelqu'un peut-il me montrer où chercher?

Merci.

Répondre

14

Vous pouvez activer la fonction glisser-déposer support pour les éléments de vue de l'arbre en mettant QtGui.QAbstractItemView.InternalMove dans la propriété dragDropMode du contrôle TreeView. Consultez également la documentation ici Using drag & drop with item views. Voici un petit exemple d'arborescence avec un glisser-déposer interne activé pour ses éléments.

import sys 
from PyQt4 import QtGui, QtCore 

class MainForm(QtGui.QMainWindow): 
    def __init__(self, parent=None): 
     super(MainForm, self).__init__(parent) 

     self.model = QtGui.QStandardItemModel() 

     for k in range(0, 4): 
      parentItem = self.model.invisibleRootItem() 
      for i in range(0, 4): 
       item = QtGui.QStandardItem(QtCore.QString("item %0 %1").arg(k).arg(i)) 
       parentItem.appendRow(item) 
       parentItem = item 

     self.view = QtGui.QTreeView() 
     self.view.setModel(self.model) 
     self.view.setDragDropMode(QtGui.QAbstractItemView.InternalMove) 

     self.setCentralWidget(self.view) 

def main(): 
    app = QtGui.QApplication(sys.argv) 
    form = MainForm() 
    form.show() 
    app.exec_() 

if __name__ == '__main__': 
    main() 

Edit0: + TreeView modèle abstrait avec drag and drop

import sys 
from PyQt4 import QtGui, QtCore 

class TreeModel(QtCore.QAbstractItemModel): 
    def __init__(self): 
     QtCore.QAbstractItemModel.__init__(self) 
     self.nodes = ['node0', 'node1', 'node2'] 

    def index(self, row, column, parent): 
     return self.createIndex(row, column, self.nodes[row]) 

    def parent(self, index): 
     return QtCore.QModelIndex() 

    def rowCount(self, index): 
     if index.internalPointer() in self.nodes: 
      return 0 
     return len(self.nodes) 

    def columnCount(self, index): 
     return 1 

    def data(self, index, role): 
     if role == 0: 
      return index.internalPointer() 
     else: 
      return None 

    def supportedDropActions(self): 
     return QtCore.Qt.CopyAction | QtCore.Qt.MoveAction   

    def flags(self, index): 
     if not index.isValid(): 
      return QtCore.Qt.ItemIsEnabled 
     return QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable | \ 
       QtCore.Qt.ItemIsDragEnabled | QtCore.Qt.ItemIsDropEnabled   

    def mimeTypes(self): 
     return ['text/xml'] 

    def mimeData(self, indexes): 
     mimedata = QtCore.QMimeData() 
     mimedata.setData('text/xml', 'mimeData') 
     return mimedata 

    def dropMimeData(self, data, action, row, column, parent): 
     print 'dropMimeData %s %s %s %s' % (data.data('text/xml'), action, row, parent) 
     return True 


class MainForm(QtGui.QMainWindow): 
    def __init__(self, parent=None): 
     super(MainForm, self).__init__(parent) 

     self.treeModel = TreeModel() 

     self.view = QtGui.QTreeView() 
     self.view.setModel(self.treeModel) 
     self.view.setDragDropMode(QtGui.QAbstractItemView.InternalMove) 

     self.setCentralWidget(self.view) 

def main(): 
    app = QtGui.QApplication(sys.argv) 
    form = MainForm() 
    form.show() 
    app.exec_() 

if __name__ == '__main__': 
    main() 

espérons que cette aide, ce qui est

+0

Merci pour votre réponse. –

+0

Merci pour votre réponse. Mais cela ne résout pas mon problème. Je sais que QStandardItemModel + QStandardItem fonctionne comme prévu. Mais j'ai besoin de le faire fonctionner en utilisant le modèle CUSTOM, sous-classe pure de QAbstractItemModel. Je pense que j'ai besoin d'implémenter certaines méthodes dans le modèle ou utiliser un objet spécialisé pour les éléments de l'arbre. Maintenant, le glisser ne montre même pas l'indicateur de chute même si cela est configuré pour être affiché ... Évidemment, je manque juste quelque chose. –

+0

J'ai encore un commentaire. Si vous prenez un exemple "simpletreemodel" dans les exemples standard de PyQt: comment ajouter un support glisser-déposer? Si je viens d'ajouter setAcceptsDrop (True), setDragEnabled (True), setDragDropMode (view.InternalMove) à afficher et flags ItemIsDragEnabled | ItemIsDropEnabled pour modéliser, il ne suffit pas d'avoir la fonctionnalité glisser-déposer. –