我正在尝试使用PyQt5实现一个文件目录。我希望在这棵树中加入拖放功能,以支持内部和外部文件(也就是说,如果我的桌面上有一些文件,我希望能够将它们放到视图中的文件夹中)。这就是我目前的情况:
from PyQt5.QtWidgets import QTreeView,QFileSystemModel,QApplication,
QMenu, QAbstractItemView
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from src import config
class Tree(QTreeView):
def __init__(self):
QTreeView.__init__(self)
cfg = config.get()
model = QFileSystemModel()
model.setRootPath("/Users/")
self.setModel(model)
self.setRootIndex(model.index("/Users/"))
self.setContextMenuPolicy(Qt.CustomContextMenu)
self.customContextMenuRequested.connect(self.open_menu)
self.setSelectionMode(self.SingleSelection)
self.setDragDropMode(QAbstractItemView.InternalMove)
self.setDragEnabled(True)
self.setAcceptDrops(True)
self.setDropIndicatorShown(True)
def open_menu(self):
menu = QMenu()
menu.addAction("Create new folder")
menu.exec_(QCursor.pos())
if __name__ == '__main__':
import sys
app = QApplication(sys.argv)
w = Main()
w.show()
sys.exit(app.exec_())使用上面的代码,我可以显示一个目录及其内容。我可以拖动一个项目,但删除它什么也不做,没有显示下降的迹象。目前还不清楚如何
让拖放在视图中工作,然后
让它处理超出上下文的项目(比如桌面)。
发布于 2018-01-05 22:59:28
根据文档
readOnly : bool 此属性保存目录模型是否允许写入文件系统。 如果此属性设置为false,则目录模型将允许重命名、复制和删除文件和目录。 默认情况下,此属性为true。
因此,如果您希望能够移动文件,则必须将其设置为False:
model.setReadOnly(False)必须覆盖dragEnterEvent方法,如果存在相对于本地资源的QUrl,则必须接受它。
然后您必须覆盖dropEvent方法,如果事件没有源,那么它意味着它作为本地文件来自外部源,然后实现一个逻辑来移动文件或目录,检查文件或目录是否存在或没有创建新的路径。
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()发布于 2018-01-05 23:10:09
在树视图子类中,必须实现dragEnterEvent、dragMoveEvent和dropEvent。
class Tree(QTreeView):
def __init__(self):
QTreeView.__init__(self)
def dragEnterEvent(self, event):
if event.mimeData().hasUrls:
event.accept()
else:
event.ignore()
def dragMoveEvent(self, event):
if event.mimeData().hasUrls:
event.setDropAction(QtCore.Qt.CopyAction)
event.accept()
else:
event.ignore()
def dropEvent(self, event):
if event.mimeData().hasUrls:
event.setDropAction(QtCore.Qt.CopyAction)
event.accept()
# to get a list of files:
drop_list = []
for url in event.mimeData().urls():
drop_list.append(str(url.toLocalFile()))
# handle the list here
else:
event.ignore()https://stackoverflow.com/questions/48121711
复制相似问题