Unsolved QTreeWidget Drag and Drop
-
Hi,
I don't have that much experience with pyQt5 so bear with me. ;-)
I'm trying to have drag and drop working on my application. I have an example from the web (can't remember where) with QTreeView. I adapted it for QTreeWidget, but it doesn't work.
My understanding is that drag and drop is not limitted to mime data. Correct?QTreeWidget Drag and Drop example (not working)
from PyQt5.QtWidgets import QTreeWidget, QTreeWidgetItem, QApplication, QAbstractItemView from PyQt5.QtCore import * from PyQt5.QtGui import * import sys class myTreeWidget(QTreeWidget): def __init__(self): QTreeWidget.__init__(self) self.setSelectionMode(self.SingleSelection) self.setDragDropMode(QAbstractItemView.InternalMove) self.setDragEnabled(True) self.setAcceptDrops(True) self.setDropIndicatorShown(True) self.setModel(self.model) self.setRootIndex(self.model.index(QDir.currentPath())) self.model.setReadOnly(False) parent = self.invisibleRootItem() child = QTreeWidgetItem(parent) child.setData() data = [ ['a','b','c','d'], ['e','f','g','h'], ['i','j','k','l'], ] self.setColumnCount(len(data[0])) parent = self.invisibleRootItem() for d in data: child = QTreeWidgetItem(parent) child.setFlags(Qt.ItemIsEditable | Qt.ItemIsEnabled | Qt.ItemIsSelectable) for col, v in enumerate(d): child.setText(col, v) parent.addChild(child) def dragEnterEvent(self, event): print('dragEnterEvent happened') event.acceptProposedAction() def dragMoveEvent(self, event): print('dragMoveEvent happened') event.acceptProposedAction() def dropEvent(self, event): print('dropEvent happened') widgetItemThatMoved=event.source().currentItem() parentThatReceivedIt=self.itemAt(event.pos()) self.theFunc(parentThatReceivedIt,widgetItemThatMoved ) event.acceptProposedAction() def functionToCallWhenDropped(self,theFunc): #this method allows you to pass a reference to this class so you assign it to a local variable for easy calling. self.theFunc=theFunc app = QApplication(sys.argv) demo = myTreeWidget() demo.show() app.exec_()
QTreeView Drag and Drop example (working)
from PyQt5.QtWidgets import QTreeView, QFileSystemModel, QApplication, QMenu, QAbstractItemView from PyQt5.QtCore import * from PyQt5.QtGui import * import sys # from src import config class Tree(QTreeView): def __init__(self): QTreeView.__init__(self) model = QFileSystemModel() model.setRootPath(QDir.currentPath()) self.setModel(model) self.setRootIndex(model.index(QDir.currentPath())) model.setReadOnly(False) self.setSelectionMode(self.SingleSelection) self.setDragDropMode(QAbstractItemView.InternalMove) self.setDragEnabled(True) self.setAcceptDrops(True) self.setDropIndicatorShown(True) def dragEnterEvent(self, event): m = event.mimeData() if m.hasUrls(): for url in m.urls(): if url.isLocalFile(): event.accept() return event.ignore() def dropEvent(self, event): if event.source(): QTreeView.dropEvent(self, event) else: ix = self.indexAt(event.pos()) if not self.model().isDir(ix): ix = ix.parent() pathDir = self.model().filePath(ix) m = event.mimeData() if m.hasUrls(): urlLocals = [url for url in m.urls() if url.isLocalFile()] accepted = False for urlLocal in urlLocals: path = urlLocal.toLocalFile() info = QFileInfo(path) n_path = QDir(pathDir).filePath(info.fileName()) o_path = info.absoluteFilePath() if n_path == o_path: continue if info.isDir(): QDir().rename(o_path, n_path) else: qfile = QFile(o_path) if QFile(n_path).exists(): n_path += "(copy)" qfile.rename(n_path) accepted = True if accepted: event.acceptProposedAction() app = QApplication(sys.argv) demo = Tree() demo.show() app.exec_()
Thanks in advance!
Denis -
Hi and welcome to devnet,
Did you already saw the Qt documentation about Drag'N'Drop with convenience view ?