首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在PyQt5 TreeView中拖放?

在PyQt5 TreeView中拖放?
EN

Stack Overflow用户
提问于 2018-01-05 21:44:39
回答 2查看 3.7K关注 0票数 1

我正在尝试使用PyQt5实现一个文件目录。我希望在这棵树中加入拖放功能,以支持内部和外部文件(也就是说,如果我的桌面上有一些文件,我希望能够将它们放到视图中的文件夹中)。这就是我目前的情况:

代码语言:javascript
复制
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_())

使用上面的代码,我可以显示一个目录及其内容。我可以拖动一个项目,但删除它什么也不做,没有显示下降的迹象。目前还不清楚如何

让拖放在视图中工作,然后

让它处理超出上下文的项目(比如桌面)。

EN

Stack Overflow用户

回答已采纳

发布于 2018-01-05 22:59:28

根据文档

readOnly : bool 此属性保存目录模型是否允许写入文件系统。 如果此属性设置为false,则目录模型将允许重命名、复制和删除文件和目录。 默认情况下,此属性为true。

因此,如果您希望能够移动文件,则必须将其设置为False:

代码语言:javascript
复制
model.setReadOnly(False)

必须覆盖dragEnterEvent方法,如果存在相对于本地资源的QUrl,则必须接受它。

然后您必须覆盖dropEvent方法,如果事件没有源,那么它意味着它作为本地文件来自外部源,然后实现一个逻辑来移动文件或目录,检查文件或目录是否存在或没有创建新的路径。

代码语言:javascript
复制
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()
票数 1
EN
查看全部 2 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48121711

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档