2010-11-12 10 views
11

En PyQt 4 Me gustaría crear un QTreeView con la posibilidad de reorganizar su estructura con la manipulación de arrastrar y soltar.QTreeView con soporte para arrastrar y soltar en PyQt

He implementado mi propio modelo (QAbstractItemModel) para QTreeView, por lo que mi QTreeView muestra correctamente los datos. Ahora me gustaría agregar soporte para arrastrar y soltar para que los nodos del árbol puedan mover un nodo dentro del árbol de uno a otro, arrastrar y copiar, etc., pero no puedo encontrar ningún tutorial completo sobre cómo lograr esto. He encontrado algunos tutoriales y consejos para QTreeWidget, pero no para QTreeView con modelo personalizado. ¿Alguien me puede indicar dónde mirar?

Gracias.

Respuesta

14

Puede habilitar arrastrar y soltar de la ventana con los elementos mediante el establecimiento de QtGui.QAbstractItemView.InternalMove en la propiedad dragDropMode del control TreeView. También eche un vistazo a la documentación aquí Using drag & drop with item views. A continuación se muestra un pequeño ejemplo de una vista de árbol con arrastrar y soltar interno habilitado para sus elementos.

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: vista de árbol + modelo abstracto con un simple arrastrar y soltar

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() 

esperanza que esta ayuda, que se refiere a

+0

Gracias por su respuesta. –

+0

Gracias por su respuesta. Pero no resuelve mi problema. Sé que el uso de QStandardItemModel + QStandardItem funciona como se esperaba. Pero tengo que hacerlo funcionar usando el modelo CUSTOM, subclase pura de QAbstractItemModel. Creo que necesito implementar algunos métodos en el modelo o usar algún objeto especializado para los elementos del árbol. Ahora el arrastre no muestra ni siquiera el indicador de caída, incluso si está configurado para mostrarse ... Obviamente me falta algo. –

+0

Tengo un comentario más. Si toma un ejemplo "simpletreemodel" en ejemplos estándar de PyQt: ¿cómo agregarle arrastrar y soltar el soporte? Si solo agrego setAcceptsDrop (True), setDragEnabled (True), setDragDropMode (view.InternalMove) para ver y flags ItemIsDragEnabled | ItemIsDropEnabled para modelar, simplemente no es suficiente para tener la funcionalidad de arrastrar y soltar. –

Cuestiones relacionadas