如何在PyQt/PySide中获取已丢弃文件的名称

14

我正在尝试设置一个应用程序,可以接受文件的拖放操作。因此,我正在寻找一种方法,在它们被拖入时提取路径。

目前,我已经启用了应用程序右侧的拖放并允许拖放文本,但我不知道如何处理拖放文件。

我正在使用:

def PTE_dragEnterEvent(self, e):
    if e.mimeData().hasFormat('text/plain'):
        e.accept()
    else:
        e.ignore() 

def PTE_dropEvent(self, e):
    newText = self.ui.fileListPTE.toPlainText() + '\n\n' + e.mimeData().text()
    self.ui.fileListPTE.setPlainText(newText)

这是对来自 Zetcode拖放教程 提供的代码进行轻微修改。


我没能完全让@ekhumoro的答案为我工作,但它给了我更多查找的地方。我发现将文件拖放到QListWidget中, 这对我有所帮助。

除了ekhumoro提出的建议之外,我还需要实现拖动事件。 我最终使用的代码如下:

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()
        
        newText = self.ui.fileListPTE.toPlainText()
        for url in event.mimeData().urls():
            newText += '\n' + str(url.toLocalFile())
        self.ui.fileListPTE.setPlainText(newText)
        self.emit(QtCore.SIGNAL("dropped"))
    else:
        event.ignore()

我认为hasUrls是一个函数,因此使用它的条件始终会评估为True - Cuadue
1个回答

20

QMimeData类具有处理拖放URL的方法。以下是一个最小工作示例:

# from PyQt4.QtGui import QApplication, QLabel
# from PySide2.QtWidgets import QApplication, QLabel
from PyQt5.QtWidgets import QApplication, QLabel

class Window(QLabel):
    def __init__(self):
        super().__init__()
        self.setAcceptDrops(True)

    def dragEnterEvent(self, event):
        print('drag-enter')
        if event.mimeData().hasUrls():
            print('has urls')
            event.accept()
        else:
            event.ignore()

    def dropEvent(self, event):
        lines = []
        for url in event.mimeData().urls():
            lines.append('dropped: %r' % url.toLocalFile())
        self.setText('\n'.join(lines))
    
app = QApplication(['Drag & Drop'])
window = Window()
window.setGeometry(50, 100, 400, 300)
window.show()
app.exec_()

更新:

关于问题的补充:

有些小部件(与上面使用的 QLabel 不同)具有默认实现的dragMoveEvent,它明确地忽略大多数事件。例如,基于 QAbstractItemView 的类可能只处理某些特定类型的移动,并忽略其他所有内容。在这种情况下,应添加重新实现 dragMoveEvent 的行为,明确接受需要以不同方式处理的事件:

class MyView(QTableView):
    ...
    def dragMoveEvent(self, event):
        if event.mimeData().hasUrls():
            event.accept()
        else:
            super().dragMoveEvent(event)

2
我注意到,如果我拖放一个文件并打印event.mimeData().urls(),它会返回类似于"/.file/id=6571367.6613263"的值,我相信这是某种OSX的临时文件。想知道如何获取正确的文件名或目录,而不是这种临时标记? - tom f

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接