简体   繁体   中英

PyQt drag and drop outside app into Windows file explorer?

I would like to create files by dragging from a QListWidget into the OS file explorer (Windows 10 in my case), is this possible? So in the widget below, I want dragging "one" and "two" from the list onto a folder in the system file explorer to create two files named "one.txt" and "two.txt" containing the text "one" and "two" respectively

import sys
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import Qt


class DragTest(QtWidgets.QListWidget):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setDragEnabled(True)
        self.addItems(['one', 'two', 'three'])
        self.setSelectionMode(self.MultiSelection)


if __name__ == "__main__":
    app = QtWidgets.QApplication.instance() or QtWidgets.QApplication(sys.argv)

    w = DragTest()
    w.show()

    app.exec_()

You need to implement the startDrag() method and add the urls to the QDrag instance.

class DragTest(QtWidgets.QListWidget):
    # ...
    def startDrag(self, actions):
        drag = QtGui.QDrag(self)
        indexes = self.selectedIndexes()
        mime = self.model().mimeData(indexes)
        urlList = []
        for index in indexes:
            urlList.append(QtCore.QUrl.fromLocalFile(index.data()))
        mime.setUrls(urlList)
        drag.setMimeData(mime)
        drag.exec_(actions)

Note that I'm just using the index.data() since you used the full path for the item name, but you might prefer to set a specific data role for the full url in case, for example, you want to show only the file name:

FullPathRole = QtCore.Qt.UserRole + 1

class DragTest(QtWidgets.QListWidget):
    # ...
    def dropEvent(self, e):
        if e.mimeData().hasUrls():
            e.setDropAction(QtCore.Qt.CopyAction)
            e.accept()
            fpath_list = []
            for url in e.mimeData().urls():
                fpath_list.append(str(url.toLocalFile()))

            for fpath in fpath_list:
                print(f'IMPORT {fpath}')
                fileName = QtCore.QFileInfo(fpath).fileName()
                item = QtWidgets.QListWidgetItem(fileName)
                item.setData(FullPathRole, fpath)
                self.addItem(fpath)

    def startDrag(self, actions):
        # ...
            urlList.append(QtCore.QUrl.fromLocalFile(index.data(FullPathRole)))

Also note that you are missing the parentheses in the if e.mimeData().hasUrls(): check.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM