在PyQt5 TreeView中拖放? [英] Drag and drop within PyQt5 TreeView?

查看:641
本文介绍了在PyQt5 TreeView中拖放?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to implement a file directory using PyQt5. I'd like to incorporate drag and drop functionality within this tree to support both internal and external files (i.e. if I had some files on my desktop I'd like to be able to drop them into a folder in my PyQt view). This is what I have currently:

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

使用上面的代码,我可以显示目录及其内容。我可以拖动一个项目,但将其拖放不会执行任何操作,也看不到任何拖放指示。

With the above code I can show a directory and its contents. I can drag an item but dropping it does nothing and no drop indication is seen. It's unclear how to

a尚不清楚。在视图中进行拖放操作,

a. get drag and drop working within the view and

b。

推荐答案

根据文档


readOnly:bool

此属性保存目录模型是否允许写入文件系统

This property holds whether the directory model allows writing to the file system

如果此属性设置为false,目录模型将允许
重命名,复制和删除文件和目录。

If this property is set to false, the directory model will allow renaming, copying and deleting of files and directories.

此属性默认为true

This property is true by default

因此,如果要移动文件,必须将其设置为False:

so if you want to be able to move files you must set it to False:

model.setReadOnly(False)

您必须覆盖 dragEnterEvent 方法,然后如果相对于本地资源有一个 QUrl ,则必须接受它。

You must overwrite the dragEnterEvent method and if there is a QUrl relative to a local resource you must accept it.

然后,您必须覆盖 dropEvent 方法以及事件是否发生s没有源,则表示它来自外部源作为本地文件,然后实施了一种逻辑来移动文件或目录,以检查文件或目录是否存在或是否创建新的一个路径。

Then you have to overwrite the dropEvent method and if the event does not have source then it implies that it comes from an external source as a local file, then a logic is implemented to move files or directories checking if the file or directory exists or not creating the new one path.

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

这篇关于在PyQt5 TreeView中拖放?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆