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
Gracias por su respuesta. –
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. –
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. –